Ankündigung

Einklappen

Sammelbestellung ETS6 Vollversionen aktiv!

Sammelbestellung für ETS6 Vollversionen (Prof., Home, Lite) mit 40% Rabatt aktiv! Infos im Forum!
Mehr anzeigen
Weniger anzeigen

Item mit Zeitberechnung bspw für Verbrauchsauswertung als Systemitems bereitstellen

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Msinn
    antwortet
    Ein Ansatzpunkt wäre, genau wie weiter oben in diesem Thread beschrieben, die Berechnungen in einem Task auszuführen (da die Berechnungen alle zeitgleich stattfinden sollen), statt für jede Berechnung
    - zu prüfen, ob ein Worker-Thread idle ist und falls ja einen Thread zu selektieren und aus der Liste der idle Threads zu entfernen
    - oder evtl. einen neuen Thread zu starten
    - den Worker-Thread aufzusetzen
    - die einzelne Berechnung durchzuführen
    - den Thread in die Liste der idle Threads aufzunehmen

    Die gesamten Berechnungen die zeitgleich ausgeführt werden sollen, könnte man in eine Logik packen und diese per crontab starten (das wäre dann im Idealfall 1 Thread statt 60). Das spart in Summe auch Rechenzeit, da das gesamte Worker-Handling nur 1 mal statt 60 mal durchgeführt werden muss.

    Zitat von kaiwerner Beitrag anzeigen
    Ich hatte vor den Änderungen immer so um die 60 Worker-Threads und keine Probleme damit. Diese haben sich genau wie jetzt, nach einem Neustart, einer nach dem anderen Aufgebaut. Aber halt da eingependelt.
    Eine andere (bewusst nicht groß dokumentierte) Möglichkeit könntest Du nutzen, da bei Deiner Hardwareausstattung und Task Beschaffenheit wie Du schreibst 60 Tasks kein Problem darstellen, ist es die Anzahl Worker-Threads bei der ein Restart ausgeführt wird zu erhöhen.

    Dazu kannst Du in ../etc/smarthome.yaml folgenden Eintrag vornehmen, um den Restart z.B. erst bei 45 Workern vorzunehmen:
    Code:
    restart_on_num_workers: 45

    Einen Kommentar schreiben:


  • bmx
    antwortet
    Zitat von kaiwerner Beitrag anzeigen
    In der Tasks werden auch nur DB-Abfragen ausgewertet, das sollte keine Ewigkeiten brauchen.
    Doch, genau das. Wenn die zeitgleich angestossen werden sollen und alle Datenbank Abfragen starten dann behindern sich die Abfragen unter Umständen schon gegenseitig...

    Einen Kommentar schreiben:


  • kaiwerner
    antwortet
    Danke für die Erklärungen.

    ich kenne diese Probleme und Beiträge "Needing more worker threads..."

    Vor allem wollte ich Deine Schedule Commit's auf keinen Fall kritisieren.
    Ich hatte vor den Änderungen immer so um die 60 Worker-Threads und keine Probleme damit. Diese haben sich genau wie jetzt, nach einem Neustart, einer nach dem anderen Aufgebaut. Aber halt da eingependelt.

    Anfangs bin ich von einem Plugin-Problem ausgegangen. So wie das Verbindungsproblem bei HUE-Plugin. Doch Abhilfe schaft bei mir nur, die stündlichen Scheduler nicht zu starten.

    Ich habe auf meinem Testsystem folgende Logeinträge.

    smarthome-details.log:2020-06-23 00:00:00 INFO lib.scheduler Adding worker thread. Total: 20
    smarthome-details.log:2020-06-23 00:00:00 INFO lib.scheduler Adding worker thread. Total: 20
    smarthome-details.log:2020-06-23 01:00:00 INFO lib.scheduler Adding worker thread. Total: 21
    smarthome-details.log:2020-06-23 01:00:00 INFO lib.scheduler Adding worker thread. Total: 21
    smarthome-details.log:2020-06-23 02:00:00 INFO lib.scheduler Adding worker thread. Total: 22
    smarthome-details.log:2020-06-23 02:00:00 INFO lib.scheduler Adding worker thread. Total: 22
    smarthome-details.log:2020-06-23 03:00:00 INFO lib.scheduler Adding worker thread. Total: 23
    smarthome-details.log:2020-06-23 03:00:00 INFO lib.scheduler Adding worker thread. Total: 23
    smarthome-details.log:2020-06-23 04:00:01 INFO lib.scheduler Adding worker thread. Total: 24
    smarthome-details.log:2020-06-23 04:00:01 INFO lib.scheduler Adding worker thread. Total: 24
    smarthome-details.log:2020-06-23 04:56:23 INFO lib.scheduler Adding worker thread. Total: 25
    smarthome-details.log:2020-06-23 04:56:23 INFO lib.scheduler Adding worker thread. Total: 25
    smarthome-details.log:2020-06-23 05:00:00 INFO lib.scheduler Adding worker thread. Total: 26
    smarthome-details.log:2020-06-23 05:00:00 INFO lib.scheduler Adding worker thread. Total: 26
    smarthome-details.log:2020-06-23 06:00:00 INFO lib.scheduler Adding worker thread. Total: 27
    smarthome-details.log:2020-06-23 06:00:00 INFO lib.scheduler Adding worker thread. Total: 27
    smarthome-details.log:2020-06-23 07:00:00 INFO lib.scheduler Adding worker thread. Total: 28
    smarthome-details.log:2020-06-23 07:00:00 INFO lib.scheduler Adding worker thread. Total: 28
    smarthome-details.log:2020-06-23 08:00:00 INFO lib.scheduler Adding worker thread. Total: 29
    smarthome-details.log:2020-06-23 08:00:00 INFO lib.scheduler Adding worker thread. Total: 29
    smarthome-details.log:2020-06-23 09:00:00 INFO lib.scheduler Adding worker thread. Total: 30
    smarthome-details.log:2020-06-23 09:00:00 INFO lib.scheduler Adding worker thread. Total: 30
    Auffällig ist das es meist zum Stundenwechsel ist und danach sind die idle Threads immer eins mehr.
    In der Tasks werden auch nur DB-Abfragen ausgewertet, das sollte keine Ewigkeiten brauchen.

    Das Du für mich vielleicht noch einen Ansatzpunkt wie ich dem Problem zu leibe Rücken kann?

    Danke


    Einen Kommentar schreiben:


  • Msinn
    antwortet
    Zitat von kaiwerner Beitrag anzeigen
    die aktuellen 5 Worker
    Wenn Du aktuell nur 5 Worker hast, Tut Dein Scheduler nicht viel (oder fast nichts). Die Erhöhung der Anzahl Worker-Threads ist seit jeher (smarthome.py) implementiert. Ab 20 Worker-Threads wurde gewarnt, dass es evtl. zu Problemen kommen kann (und evtl. auch tut. Siehe diverse Threads hier im Forum dazu, z.B. zum HUE Plugin). Neu ist nur, dass ab 30 Threads neu gestartet wird, statt zu warten bis SmartHomeNG sich "festfräst" und nicht mehr reagiert.

    Zitat von kaiwerner Beitrag anzeigen
    Durch die Änderung von msinn lib.scheduler: Implemented restart of SmartHomeNG if number of worker… werden die _restart_on_num_workers (30 Stück) nach einem Tag erreicht und ein Neustart ausgeführt.
    falsch, sonst hättest Du bisher schon keine 5 Worker sondern Warnungen, dass Du die 20 Worker-Threads überschreitest.

    Zitat von kaiwerner Beitrag anzeigen
    Habe ich das richtig verstanden?
    zum Teil

    Zitat von kaiwerner Beitrag anzeigen
    Ist das so gewollt?
    Ja

    Zitat von kaiwerner Beitrag anzeigen
    Sind die ca. 70 Schedulern die zum Stundenwechsel triggern zuviel?
    Nein, es sei denn Du hast einen Raspi 1 o.Ä. im Einsatz und/oder Deine Tasks brauchen Ewigkeiten um ihre Berechnungen durchzuführen.

    Zitat von kaiwerner Beitrag anzeigen
    Wäre es nicht besser die Worker zu begrenzen und die Queue weiter abzuarbeiten, wenn wieder einer frei ist?
    Genau da passiert doch. Deshalb wird nur ein Worker-Thread je Minute erzeugt und nur, wenn keiner der existierenden Worker-Threads idle ist. (Das ist übrigens seit Urzeiten so).
    Du läufst also nur in Probleme, wenn Deine durch crontab ausgelösten Berechnungen jeweils länger als eine Minute benötigen.

    Einen Kommentar schreiben:


  • kaiwerner
    antwortet
    Hallo zusammen,

    ich weiß nicht ob ich hier jetzt out of topic bin. Sorry.
    Ich benutze auch einige Berechnungen an Items die, ähnlich wie die Verbrauchsauswertung, mit crontabs stündlich und / oder tageweise getriggert werden.
    Wenn jetzt zum Stunden- oder Tageswechsel 60-70 Scheduler triggern reichen die aktuellen 5 Worker nicht aus und es wird ein neuer Worker erzeugt.
    Da die Abarbeitung der getriggerten Scheduler aber innerhalb der 60 Sekunden von _worker_delta erfolgt wird jede Stunde, bei erneuten triggern, ein weiterer Worker erzeugt.
    Durch die Änderung von msinn lib.scheduler: Implemented restart of SmartHomeNG if number of worker… werden die _restart_on_num_workers (30 Stück) nach einem Tag erreicht und ein Neustart ausgeführt.

    Habe ich das richtig verstanden? Ist das so gewollt? Sind die ca. 70 Schedulern die zum Stundenwechsel triggern zuviel? Wäre es nicht besser die Worker zu begrenzen und die Queue weiter abzuarbeiten, wenn wieder einer frei ist? Oder habe ich da was nicht durchschaut?

    Vielen Dank.

    Einen Kommentar schreiben:


  • Onkelandy
    antwortet
    Gemäß https://knx-user-forum.de/forum/supp...99#post1508399 ist es Vorwoche. Hab mir aber nicht übermäßig viel Gedanken dazu gemacht. Ansonsten Sisamiwe alles so wie du geschrieben hast. Ließe sich bestimmt noch optimieren.

    Msinn hat auch Recht, dass man die Wochenwerte immer eine Ebene weiter nach unten kopieren könnte. Selbes natürlich auch mit mit den anderen "minusX" Werten.
    Zuletzt geändert von Onkelandy; 15.06.2020, 23:22.

    Einen Kommentar schreiben:


  • Msinn
    antwortet
    Ohne das im Detail mitverfolgt zu haben. Eine Logik müsste eigentlich nur auf woche triggern und bei der Ausführung einfach die bisherigen Wochen-Werte auf die Vorwoche Items kopieren bevor sie ihre eigentlichen Berechnungen durchführt... oder habe ich die Diskussion misverstanden?

    Einen Kommentar schreiben:


  • Sisamiwe
    antwortet
    Zitat von Onkelandy Beitrag anzeigen
    Da nun aber auch andere Items ein "gestern" haben könnten, hab ich bei mir das Struct in ein Unteritem "wertehistorie" gesteckt. Dann muss man die relativen Itemangaben mit einem weiteren Punkt bestücken, also zB sh....db statt sh...db

    Wildcards funktionieren nicht wirklich, aber normale substring Vergleiche. Meine Logik sieht nun so aus, muss ich aber noch ne Zeit testen.
    Danke für den Vorschlag. Ich versuche das noch nachzuvollziehen, denke auch verstanden zu haben, wie es funktionieren soll. Aber so ganz bin ich noch nicht dabei.

    Dein Item sieht bspw so aus:
    Code:
    %YAML 1.1
    ---
    stromzaehler:
        bezug:
            energie:
                name: Wirkarbeit Bezug total
                type: num
                sml_obis: 1-0:1.8.0*255
                sml_prop: valueReal
                eval: round(value / 1000, 2)
                database: init
    
                wertehistorie:
                    struct: wertehistorie_total
    Richtig?

    Mit der Logik machst du folgendes:
    Zitat von Onkelandy Beitrag anzeigen
    if not hasattr(logic, 'all_items'): logic.all_items = items.return_items()
    Es wird für die Logik eine persistente Variable erstellt, in der alle Items sind.

    Zitat von Onkelandy Beitrag anzeigen
    for item in logic.all_items: if not "wertehistorie" in item.property.path: pass
    Wenn "wertehistorie" (= Name des Unteritems mit dem struct) nicht im Pfad des Items vorkommt, dann fertig.

    Zitat von Onkelandy Beitrag anzeigen
    elif sh.now().strftime("%H") == "0" and sh.now().strftime("%M") == "0" and ("wertehistorie.gestern" in item.property.path or "wertehistorie.vorwoche" in item.property.path): item(1)
    Wenn "wertehistorie" im Itempfad und Stunden und Minuten zur Zeit der Logikausführung = 0 und ("wertehistorie.gestern" oder "wertehistorie.vorwoche") im Itempfad, dann wird das Item auf "1" gesetzt, also getriggert.

    Ist meine Interpretation korrekt?
    Wenn ja, warum triggerst Du "vorwoche" um 0:00? das müsste doch "woche" sein, oder?

    Einen Kommentar schreiben:


  • Onkelandy
    antwortet
    Die Lösung hab ich ja schon gepostet: https://knx-user-forum.de/forum/supp...55#post1516755

    Dadurch gibt es nur einen Scheduler Task der zu Mitternacht ausgeführt wird.

    Einen Kommentar schreiben:


  • bmx
    antwortet
    Naja was erwartest Du? Jedes mal wenn der Zähler sich ändert, gibt es 4 Datenbankabfragen und die brauchen halt Zeit. Wenn Du dieses Struct mehrfach nutzt, dann vervielfacht sich das natürlich.

    Wozu mußt Du jedesmal bei Zähleränderung den Jahresstand neu berechnen?
    Vielleicht sollte man sich fragen wozu man diese Werte eigentlich braucht? Nur für die Visu? Wozu eine solche Genauigkeit? Reicht es da nicht einfach bei Bedarf die Werte neu zu berechnen?
    Zuletzt geändert von bmx; 15.06.2020, 13:20.

    Einen Kommentar schreiben:


  • z1marco
    antwortet
    Hi Michael, Onkelandy,

    das mit stündlich hab ich verworfen. Ich hab aber das Gefühl, seit ich dieses struct eingeführt hab, läuft smarthomeng mit längerer Laufzeit nicht mehr. Schaltbefehle kommen nicht mehr auf dem KNX an. Nach einem Neustart geht es wieder. In der Smartvisu Monitor Smarthomeng gehen die Threads auf 33 und Systemload auf 0,58.
    Habt Ihr eine Idee wie ich das eingrenzen kann und wo ich noch was prüfen kann? Bin nicht sicher ob es daran liegt, nur eine Vermutung.
    Das struckt nutzte ich nur für die Verbrauchsitems.

    vielen Dank Euch für die Unterstützung

    Einen Kommentar schreiben:


  • z1marco
    antwortet
    Hallo Michael,

    danke für Deine Geduld. So langsam verstehe ich Deinen Ansatz. Ich hatte vorher mit der Zeitlogik gearbeitet und auch die stündlichen Werte. Ich hatte ein Diagramm welches den Tagesverlauf zeigt und dort sieht man dann schön wann die Heizung oder andere Verbraucher am Tag angeschaltet wurden. Dafür wurden die stündlichen Werte verwendet. Das ganze hatte ich immer nur für die letzten 3 Tage. Ich muss da nochmal drüber nachdenken.

    Wie hast Du Deine Werte visualisiert.

    Gruß Marco

    Einen Kommentar schreiben:


  • Sisamiwe
    antwortet
    Hallo z1marco,

    mir ist noch nicht wirklich klar, was du machen willst.

    Bei mir gibt es immer ein Item, dass mit dem Zählerstand oder ähnlichem versorgt wird. Bspw so:
    Code:
    %YAML 1.1
    ---
    stromzaehler:
        bezug:
            energie:
                name: Wirkarbeit Bezug total
                type: num
                sml_obis: 1-0:1.8.0*255
                sml_prop: valueReal
                eval: round(value / 1000, 2)
                database: init
                struct: wertehistorie_total
    Darin wird das struct auch angezogen.

    Das struct von mir ist so angelegt, dass alle Items, die einen Verrauch bis JETZT haben, durch das Zählerstandsitem getriggert werden und somit neu berechnet werden. Dafür sorgt der
    Code:
    eval_trigger: ..
    Code:
    wertehistorie_total:
        name: Struct für Wertehistorie total
        heute:
            type: num
            visu_acl: ro
            eval: round((sh...() - sh...db('max', str(shtime.time_since(shtime.today(), 'im')) + 'i', str(shtime.time_since(shtime.today(), 'im')) + 'i')), 2)
            eval_trigger:
              - ..
            cache: yes
    
        woche:
            type: num
            visu_acl: ro
            eval: round((sh...() - sh...db('max', str(shtime.time_since(shtime.beginning_of_week(), 'im')) + 'i', str(shtime.time_since(shtime.beginning_of_week(), 'im')) + 'i')), 2)
            eval_trigger:
              - ..
            cache: yes
    
        monat:
            type: num
            visu_acl: ro
            eval: round((sh...() - sh...db('max', str(shtime.time_since(shtime.beginning_of_month(), 'im')) + 'i', str(shtime.time_since(shtime.beginning_of_month(), 'im')) + 'i')), 2)
            eval_trigger:
              - ..
            cache: yes
    
        jahr:
            type: num
            visu_acl: ro
            eval: round((sh...() - sh...db('max', str(shtime.time_since(shtime.beginning_of_year(), 'im')) + 'i', str(shtime.time_since(shtime.beginning_of_year(), 'im')) + 'i')), 2)
            eval_trigger:
              - ..
            cache: yes
    Somit werden diese Items immer aktualisiert, sobald der Zählerstand sich ändert. Warum sollen diese Items auch noch stündlich aktualisiert werden?

    Die anderen Items, die einen ehemaligen Verbrauch anzeigen, ändern sich nur mit Wechsel der Tages-, Monats- oder Jahresgrenze. Auch diese Items müssen sich nicht alle Stunde aktualisieren. Denn der Verbrauch von gestern ist im 9.00 Uhr noch der gleiche wie im 10.00 Uhr oder 11.00 Uhr.

    Was meinst Du mit
    Zitat von z1marco Beitrag anzeigen
    stündliche Auswertung

    Einen Kommentar schreiben:


  • z1marco
    antwortet
    Hallo Michael,

    ich versuche gerade in Deinem struct noch die Auswertung stündlich zu ergänzen. Das fällt mir echt schwer. Könntest Du mir dabei behilflich sein. Wie würdest Du die stündliche Auswertung über Dein Struct machen?
    Ich würde den crontab auf stündlich setzen: crontab = 0 * * * = 1
    Aber die Berechnung mit shtime macht mir Kopfzerbrechen.

    Hast Du auch eine Visualisierung auf die Verbrauchswerte? Was nutzt Du da?

    Gruß und Danke

    P.S.: Deine restlichen Werte werden wunderbar in die DB geschrieben. Super Lösung.

    Einen Kommentar schreiben:


  • Onkelandy
    antwortet
    Danke für die Rückmeldung Sisamiwe bezüglich des Triggerns auf Basis des parent items. Macht Sinn. Und prinzipiell ist es genau so wie du geschrieben hattest. Da nun aber auch andere Items ein "gestern" haben könnten, hab ich bei mir das Struct in ein Unteritem "wertehistorie" gesteckt. Dann muss man die relativen Itemangaben mit einem weiteren Punkt bestücken, also zB sh....db statt sh...db

    Wildcards funktionieren nicht wirklich, aber normale substring Vergleiche. Meine Logik sieht nun so aus, muss ich aber noch ne Zeit testen.
    Code:
    if not hasattr(logic, 'all_items'):
        logic.all_items = items.return_items()
    
    for item in logic.all_items:
        if not "wertehistorie" in item.property.path:
            pass
        elif sh.now().strftime("%H") == "0" and sh.now().strftime("%M") == "0" and ("wertehistorie.gestern" in item.property.path or "wertehistorie.vorwoche" in item.property.path):
            item(1)
        elif sh.now().strftime("%d") == "1" and "wertehistorie.vormonat" in item.property.path:
            item(1)
    logic.yaml:
    Code:
    wertehistorie:
        filename: wertehistorie.py
        crontab:
        -   init+200
        -   '0 0 * *'

    Einen Kommentar schreiben:

Lädt...
X