Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. JavaScript
  5. Zykl. getState-Aufrufe vs. eigenes "Cache-Dictionary"

NEWS

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    8.8k

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    13
    1
    2.2k

  • Neues Video "KI im Smart Home" - ioBroker plus n8n
    BluefoxB
    Bluefox
    16
    1
    3.2k

Zykl. getState-Aufrufe vs. eigenes "Cache-Dictionary"

Geplant Angeheftet Gesperrt Verschoben JavaScript
18 Beiträge 3 Kommentatoren 1.3k Aufrufe 2 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • F Offline
    F Offline
    Familienvater
    schrieb am zuletzt editiert von
    #1

    Moin,

    ich habe hier und mit google gesucht, mich ausführlich mit ChatGPT unterhalten, aber javaScript ist (noch) nicht meins, ich bin inzwischen beruflich sehr viel mit c# in Unity unterwegs, Programmieren an sich ist weniger das Problem...
    Also, für Entscheidungen in ioBroker, unter welchen Bedingungen Geräte z.B. ein-/ausgeschaltet werden sollen, um den Eigenverbrauch zu optimieren, habe ich die Einspeise- und Bezugsdatenpunkt von meinem Discovergy-Stromzähler-Adapter in js "abonniert", und sollte alle 5 Sekunden neue Werte bekommen.

    Da ich (mit mir meine ich meistens die Logik in ioBroker) für die Entscheidungen, "viele" andere Datenpunkte in Betracht ziehen will, stelle ich mir die Frage, wie "teuer" ein getState alle 5 Sekunden ist (mal x-Datenpunkte), wenn sich der Wert evtl. nur alle paar Minuten oder noch seltener ändert.

    Da ich gerne "groß" denke, suche ich nach einer pflegeleichten Lösung, eigentlich hätte ich gerne etwas in der folgenden Art, aber "automatisiert" mit vielleicht einem 2-Zeiler:

    const idFernseherAn = 'adapter.instanz.bla.blub';
    let FernseherAn = getState(idFernseherAn); // absichtlich State, weil mich evtl. auch .lc interessiert
    on({id: idFernseherAn  ,change:'any'}, function (obj) {
    FernseherAn = obj.state;
        });
    
    // FernseherAn  sollte jetzt immer "aktuell" sein, ohne das alle 5 Sekunden getState aufgerufen werden muss
    

    Wunsch:

    const idFernseherAn = 'adapter.instanz.bla.blub';
    let FernseherAn = MagicFunction(idFernseherAn, FernseherAn); 
    // return der Function ist der initiale getState, und die MagicFunction registriert 
    // die on-Subscription für den Datenpunkt, und "erstellt" die Callback-Function so, 
    // das die übergebene Variable als Referenz aktuell gehalten wird, wenn sich der zugrundeliegende Datenpunkt ändert
    

    Aktueller Lösungsansatz:

    const dataPoints = {};
    const idFernseherAn = 'adapter.instanz.bla.blub';
    
    // Initialisieren Sie die Cache-Objekte für jede Datenpunkt-ID
    SetupCacheStateVariable(idFernseherAn);
        
    function SetupCacheStateVariable(idDataPoint)
    {
        dataPoints[idDataPoint] = getState(idDataPoint);
        on({id: idDataPoint, change:'any'}, function (obj) {
            UpdateCache(obj);
        });
    }
    
    function UpdateCache(obj)
    {
        dataPoints[obj.id] = obj.state;
    }
    
    // Zugriff mit z.B. dataPoints[idFernseherAn].val
    

    Wie gesagt, ich denke "groß", und habe aktuell sicherlich 20 Datenpunkte, die ich zyklisch für die Entscheidung, einschalten, an lassen, ausschalten oder womöglich auch "umkonfigurieren" durchkauen lasse.

    Eigentlich würde ich lieber mit Variablennamen arbeiten, und nicht alles über Zugriffe auf das Dictionary lösen.

    Jetzt noch zwei Gretchenfragen:
    Nach dem ich jetzt mal in TypeScript reingeschnuppert habe, und ich eigentlich die strikte-Typprüfung zum Compile-Zeitpunkt ala c# mag, wäre so etwas mit TypeScript "einfacher"/anders/besser lösbar?

    Würde es sich anbieten, oder verbieten, den ganzen Cache-Kram in ein Sourcefile im global-Folder zu packen? Dann müsste man im SetupCacheStateVariable prüfen, ob es den Key noch nicht gibt, und nur dann die Subscription machen.
    Pro: Ein Cache-Object für alle Source-Files, evtl. weniger Subscribes im ganzen auf häufiger benötigte Datenpunkte, weil einmal Zentral und nicht n-mal in x-Sourcefiles
    Contra: Beim Beenden eines Sourcefiles wird keine Subscription gelöscht, wenn am global-File was geändert wird, muss eh die komplette JS-Adapterinstanz neu getartet werden?
    Contra: Unmöglich zu debuggen/nachzuvollziehen?
    Unklar: Könnte Threading ein Issue sein oder schwer zu findende RaceConditions auslösen (ich habe da manchmal Spaß mit c# und "fremdem" Code)?

    Schubst mich bitte mal in die ein oder andere Richtung, hoffentlich in die richtige...

    Danke,
    Christian

    OliverIOO 1 Antwort Letzte Antwort
    0
    • F Familienvater

      Moin,

      ich habe hier und mit google gesucht, mich ausführlich mit ChatGPT unterhalten, aber javaScript ist (noch) nicht meins, ich bin inzwischen beruflich sehr viel mit c# in Unity unterwegs, Programmieren an sich ist weniger das Problem...
      Also, für Entscheidungen in ioBroker, unter welchen Bedingungen Geräte z.B. ein-/ausgeschaltet werden sollen, um den Eigenverbrauch zu optimieren, habe ich die Einspeise- und Bezugsdatenpunkt von meinem Discovergy-Stromzähler-Adapter in js "abonniert", und sollte alle 5 Sekunden neue Werte bekommen.

      Da ich (mit mir meine ich meistens die Logik in ioBroker) für die Entscheidungen, "viele" andere Datenpunkte in Betracht ziehen will, stelle ich mir die Frage, wie "teuer" ein getState alle 5 Sekunden ist (mal x-Datenpunkte), wenn sich der Wert evtl. nur alle paar Minuten oder noch seltener ändert.

      Da ich gerne "groß" denke, suche ich nach einer pflegeleichten Lösung, eigentlich hätte ich gerne etwas in der folgenden Art, aber "automatisiert" mit vielleicht einem 2-Zeiler:

      const idFernseherAn = 'adapter.instanz.bla.blub';
      let FernseherAn = getState(idFernseherAn); // absichtlich State, weil mich evtl. auch .lc interessiert
      on({id: idFernseherAn  ,change:'any'}, function (obj) {
      FernseherAn = obj.state;
          });
      
      // FernseherAn  sollte jetzt immer "aktuell" sein, ohne das alle 5 Sekunden getState aufgerufen werden muss
      

      Wunsch:

      const idFernseherAn = 'adapter.instanz.bla.blub';
      let FernseherAn = MagicFunction(idFernseherAn, FernseherAn); 
      // return der Function ist der initiale getState, und die MagicFunction registriert 
      // die on-Subscription für den Datenpunkt, und "erstellt" die Callback-Function so, 
      // das die übergebene Variable als Referenz aktuell gehalten wird, wenn sich der zugrundeliegende Datenpunkt ändert
      

      Aktueller Lösungsansatz:

      const dataPoints = {};
      const idFernseherAn = 'adapter.instanz.bla.blub';
      
      // Initialisieren Sie die Cache-Objekte für jede Datenpunkt-ID
      SetupCacheStateVariable(idFernseherAn);
          
      function SetupCacheStateVariable(idDataPoint)
      {
          dataPoints[idDataPoint] = getState(idDataPoint);
          on({id: idDataPoint, change:'any'}, function (obj) {
              UpdateCache(obj);
          });
      }
      
      function UpdateCache(obj)
      {
          dataPoints[obj.id] = obj.state;
      }
      
      // Zugriff mit z.B. dataPoints[idFernseherAn].val
      

      Wie gesagt, ich denke "groß", und habe aktuell sicherlich 20 Datenpunkte, die ich zyklisch für die Entscheidung, einschalten, an lassen, ausschalten oder womöglich auch "umkonfigurieren" durchkauen lasse.

      Eigentlich würde ich lieber mit Variablennamen arbeiten, und nicht alles über Zugriffe auf das Dictionary lösen.

      Jetzt noch zwei Gretchenfragen:
      Nach dem ich jetzt mal in TypeScript reingeschnuppert habe, und ich eigentlich die strikte-Typprüfung zum Compile-Zeitpunkt ala c# mag, wäre so etwas mit TypeScript "einfacher"/anders/besser lösbar?

      Würde es sich anbieten, oder verbieten, den ganzen Cache-Kram in ein Sourcefile im global-Folder zu packen? Dann müsste man im SetupCacheStateVariable prüfen, ob es den Key noch nicht gibt, und nur dann die Subscription machen.
      Pro: Ein Cache-Object für alle Source-Files, evtl. weniger Subscribes im ganzen auf häufiger benötigte Datenpunkte, weil einmal Zentral und nicht n-mal in x-Sourcefiles
      Contra: Beim Beenden eines Sourcefiles wird keine Subscription gelöscht, wenn am global-File was geändert wird, muss eh die komplette JS-Adapterinstanz neu getartet werden?
      Contra: Unmöglich zu debuggen/nachzuvollziehen?
      Unklar: Könnte Threading ein Issue sein oder schwer zu findende RaceConditions auslösen (ich habe da manchmal Spaß mit c# und "fremdem" Code)?

      Schubst mich bitte mal in die ein oder andere Richtung, hoffentlich in die richtige...

      Danke,
      Christian

      OliverIOO Offline
      OliverIOO Offline
      OliverIO
      schrieb am zuletzt editiert von OliverIO
      #2

      @familienvater

      warum willst du einen weiteren cache aufbauen?
      iobroker ist doch schon dein cache für die datenpunkte?

      wenn du einen weiteren "cache" dazu baust, baust du eine zusätzliche logikschicht ein, welche einfach noch ein paar millisekunden extra läuft, obwohl du es nicht benötigst.

      oder ist deine absicht, den trigger aufruf mit on für dich zu standardisieren/vereinfachen? Das sehe ich in deinen Beispielen nicht, was das ziel sein könnte

      global skripte werden nur zum jeweiligen skript beim ablauf dazukopiert .
      sie laufen im jeweiligen kontext des einzelnen skripts. die eine global funktion weiß nix von der anderen global funktion mit dem gleichen namen und teilt sich auch nicht die variablen-inhalt

      optimierung der subscribes. hast du tatsächlich soviele überlappende subscribes für den gleichen datenpunkt?
      wenn dann lieber die verschiedenen logiken eines datenpunktes zu einem on zusammenfassen und da behandeln.

      Meine Adapter und Widgets
      TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
      Links im Profil

      F 1 Antwort Letzte Antwort
      1
      • OliverIOO OliverIO

        @familienvater

        warum willst du einen weiteren cache aufbauen?
        iobroker ist doch schon dein cache für die datenpunkte?

        wenn du einen weiteren "cache" dazu baust, baust du eine zusätzliche logikschicht ein, welche einfach noch ein paar millisekunden extra läuft, obwohl du es nicht benötigst.

        oder ist deine absicht, den trigger aufruf mit on für dich zu standardisieren/vereinfachen? Das sehe ich in deinen Beispielen nicht, was das ziel sein könnte

        global skripte werden nur zum jeweiligen skript beim ablauf dazukopiert .
        sie laufen im jeweiligen kontext des einzelnen skripts. die eine global funktion weiß nix von der anderen global funktion mit dem gleichen namen und teilt sich auch nicht die variablen-inhalt

        optimierung der subscribes. hast du tatsächlich soviele überlappende subscribes für den gleichen datenpunkt?
        wenn dann lieber die verschiedenen logiken eines datenpunktes zu einem on zusammenfassen und da behandeln.

        F Offline
        F Offline
        Familienvater
        schrieb am zuletzt editiert von
        #3

        @oliverio
        Wie gesagt, mir ist nicht klar, wie "teuer" (overHead) ein getState Aufruf ist, oder ob das im Hintergrund auch nur eine Abfrage auf ein Dictionary ist.
        Sicherlich wird ein, oder auch 20 getState-Aufrufe ioBroker nicht ins stocken bringen, aber macht man es einmal so, und es funktioniert, dann macht man es evtl. immer so, und dann rächt es sich irgendwann, und dann stellt man fest, das "alles" Grütze ist.

        Ich bin schon immer ein Freund der Event getriebenen Programmierung, und ein "zyklisches" Pollen (abfragen) von Zuständen ist mir von meiner Programmierlogik zuwider, ich vergleiche das gerne mit dem gemütlichen Menschen, der vor dem Fernseher sitzt, und wartet, bis es an der Türe klingelt, oder bei dem sich die Blase meldet, und er dann auf Toilette geht. Dem stehen die zyklischen Programmieransätze entgegen, wo Bildliche gesprochen einer alle 5 Sekunden an die Türe rennt, und schaut, ob da jemand ist, und dann zur Toilette rennt, und schaut, ob was kommt, und sich dann wieder vor den Fernseher setzt.

        Vielleicht versteht man jetzt eher mein Hintergedanken, vielleicht sehe ich aber auch einfach ein Problem, wo kein Problem existiert, und ich bin nur von c#/unity getrieben, alles so CPU-Zyklen schonend/frameraten-freundlich zu erstellen, wie möglich, weil sich auch da alles bei einem oder nur ein paar Objekten absolut performance-Neutral verhält, aber später dann, wenn es zum richtigen Einsatz kommt, ist es auf einmal mit tausenden von Objekten überhaupt gar nicht mehr so performant.

        Christian

        OliverIOO 1 Antwort Letzte Antwort
        0
        • F Familienvater

          @oliverio
          Wie gesagt, mir ist nicht klar, wie "teuer" (overHead) ein getState Aufruf ist, oder ob das im Hintergrund auch nur eine Abfrage auf ein Dictionary ist.
          Sicherlich wird ein, oder auch 20 getState-Aufrufe ioBroker nicht ins stocken bringen, aber macht man es einmal so, und es funktioniert, dann macht man es evtl. immer so, und dann rächt es sich irgendwann, und dann stellt man fest, das "alles" Grütze ist.

          Ich bin schon immer ein Freund der Event getriebenen Programmierung, und ein "zyklisches" Pollen (abfragen) von Zuständen ist mir von meiner Programmierlogik zuwider, ich vergleiche das gerne mit dem gemütlichen Menschen, der vor dem Fernseher sitzt, und wartet, bis es an der Türe klingelt, oder bei dem sich die Blase meldet, und er dann auf Toilette geht. Dem stehen die zyklischen Programmieransätze entgegen, wo Bildliche gesprochen einer alle 5 Sekunden an die Türe rennt, und schaut, ob da jemand ist, und dann zur Toilette rennt, und schaut, ob was kommt, und sich dann wieder vor den Fernseher setzt.

          Vielleicht versteht man jetzt eher mein Hintergedanken, vielleicht sehe ich aber auch einfach ein Problem, wo kein Problem existiert, und ich bin nur von c#/unity getrieben, alles so CPU-Zyklen schonend/frameraten-freundlich zu erstellen, wie möglich, weil sich auch da alles bei einem oder nur ein paar Objekten absolut performance-Neutral verhält, aber später dann, wenn es zum richtigen Einsatz kommt, ist es auf einmal mit tausenden von Objekten überhaupt gar nicht mehr so performant.

          Christian

          OliverIOO Offline
          OliverIOO Offline
          OliverIO
          schrieb am zuletzt editiert von OliverIO
          #4

          @familienvater

          ja pollen ist schlecht.
          der on-befehl macht nur was, wenn eine echte veränderung am datenpunkt passiert

          ein link zum hintergrund
          iobroker verwendet socket io (welche version habe ich nicht nachgeschaut ob 3 oder schon 4)
          https://socket.io/docs/v4/

          der javascript adapter und die ganzen visualisierungen verwendet socket io als client.

          Meine Adapter und Widgets
          TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
          Links im Profil

          1 Antwort Letzte Antwort
          0
          • F Offline
            F Offline
            Familienvater
            schrieb am zuletzt editiert von
            #5

            Habe jetzt eher zufällig eine Antwort gefunden:

            das ganze in den global-folder macht es trotzdem nicht global für alle sourcefiles, weil es wird ja nur das global-File Zeugs vor jedes individuelle Source-File Zeugs gepackt.
            Um von einem Sourcefile in ein anderes zu "kommunizieren", muss man Datapoints nutzen...

            Christian

            OliverIOO 1 Antwort Letzte Antwort
            0
            • F Familienvater

              Habe jetzt eher zufällig eine Antwort gefunden:

              das ganze in den global-folder macht es trotzdem nicht global für alle sourcefiles, weil es wird ja nur das global-File Zeugs vor jedes individuelle Source-File Zeugs gepackt.
              Um von einem Sourcefile in ein anderes zu "kommunizieren", muss man Datapoints nutzen...

              Christian

              OliverIOO Offline
              OliverIOO Offline
              OliverIO
              schrieb am zuletzt editiert von
              #6

              @familienvater
              deren zugriff und abruf performancemäßig auch nicht umsonst (aber auch nicht so teuer sind)

              aber wenn du 20 skripte hast, dann werden bei der änderung eines datenpunktes in deinem cache 20 skripte informiert.

              und ich frag mal nochmal zu sicherheit und rein rhetorisch:
              was wolltest du damit einsparen?

              Meine Adapter und Widgets
              TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
              Links im Profil

              F 1 Antwort Letzte Antwort
              0
              • OliverIOO OliverIO

                @familienvater
                deren zugriff und abruf performancemäßig auch nicht umsonst (aber auch nicht so teuer sind)

                aber wenn du 20 skripte hast, dann werden bei der änderung eines datenpunktes in deinem cache 20 skripte informiert.

                und ich frag mal nochmal zu sicherheit und rein rhetorisch:
                was wolltest du damit einsparen?

                F Offline
                F Offline
                Familienvater
                schrieb am zuletzt editiert von
                #7

                @oliverio
                Da der Cache letztendlich doch Sourcefile-Abhängig ist, hat er auch nur die Subscriptions, die in diesem Sourcefile gemacht wurden.
                Die "Core-Funktionalität" wollte/würde ich ins global packen, das "dynamische" Zufügen der Datenpunkte natürlich schon aus den individuellen Sourcefiles.
                Wäre global ein echtes Global hätte jedes Sourcefile versucht, in einem globalen-Sourcefile Datenpunkte ins Cache-Directory zuzufügen, und alle anderen, die den gleiche Datenpunkt auch abonniert hätten wollen, hätten von der schon vorhandenen Subscription in der globalen Instanz profitiert. Ist aber nicht global, sondern doch Sourcefile-Abhängig, also hat/hätte jedes Sourcefile seine eigenen Subscriptions, egal ob die im globalen Sourcefile gemacht werden, oder im individuellen Sourcefile.

                Da aber ein globales Function-Repository einfacher zu Pflegen ist, als 20x Copy-Paste-Code in 20 verschiedenen Sourcefiles (doppelte Daten/Sourcecode-Vorhaltung neigt zu Inkonsistenzen), werde ich den globalen Ansatz verfolgen.
                Da getState wegen dem dazwischenliegenden socket.io anscheinend auch noch richtigen "Kommunikations-Overhead" zwischen dem Adapter und dem Kern erzeugt, scheint mir das Caching-Directory gar keine so schlechte Idee zu sein, wenn man groß denkt, selbst wenn es dafür mehr subscriptions gibt, die triggern ja wieder nur, wenn sich was subscribiertes ändert.
                Und bei ggf. alle 5 min eine Änderung per Subscription erspart in den 300 Sekunden 60x getState, kann die Subscription mit ggf. 60x Directory-Lookup gar nicht so teuer sein, wenn 60x socket.io Zugriffe gespart werden, pro Variable.

                Weil das javaScript halt kein c# ist, kann man wohl auch nicht "einfach" gewissen Funktionalitäten in Klassen kapseln, und muss sich gut überlegen, welche Funktion im global wirklich in "jedem" Sourcefile benötigt wird, weil es wieder nicht einfach nicht individuell optional dazu gebucht werden kann, so in der Art eines require("") oder "using".

                Christian

                OliverIOO 1 Antwort Letzte Antwort
                0
                • F Familienvater

                  @oliverio
                  Da der Cache letztendlich doch Sourcefile-Abhängig ist, hat er auch nur die Subscriptions, die in diesem Sourcefile gemacht wurden.
                  Die "Core-Funktionalität" wollte/würde ich ins global packen, das "dynamische" Zufügen der Datenpunkte natürlich schon aus den individuellen Sourcefiles.
                  Wäre global ein echtes Global hätte jedes Sourcefile versucht, in einem globalen-Sourcefile Datenpunkte ins Cache-Directory zuzufügen, und alle anderen, die den gleiche Datenpunkt auch abonniert hätten wollen, hätten von der schon vorhandenen Subscription in der globalen Instanz profitiert. Ist aber nicht global, sondern doch Sourcefile-Abhängig, also hat/hätte jedes Sourcefile seine eigenen Subscriptions, egal ob die im globalen Sourcefile gemacht werden, oder im individuellen Sourcefile.

                  Da aber ein globales Function-Repository einfacher zu Pflegen ist, als 20x Copy-Paste-Code in 20 verschiedenen Sourcefiles (doppelte Daten/Sourcecode-Vorhaltung neigt zu Inkonsistenzen), werde ich den globalen Ansatz verfolgen.
                  Da getState wegen dem dazwischenliegenden socket.io anscheinend auch noch richtigen "Kommunikations-Overhead" zwischen dem Adapter und dem Kern erzeugt, scheint mir das Caching-Directory gar keine so schlechte Idee zu sein, wenn man groß denkt, selbst wenn es dafür mehr subscriptions gibt, die triggern ja wieder nur, wenn sich was subscribiertes ändert.
                  Und bei ggf. alle 5 min eine Änderung per Subscription erspart in den 300 Sekunden 60x getState, kann die Subscription mit ggf. 60x Directory-Lookup gar nicht so teuer sein, wenn 60x socket.io Zugriffe gespart werden, pro Variable.

                  Weil das javaScript halt kein c# ist, kann man wohl auch nicht "einfach" gewissen Funktionalitäten in Klassen kapseln, und muss sich gut überlegen, welche Funktion im global wirklich in "jedem" Sourcefile benötigt wird, weil es wieder nicht einfach nicht individuell optional dazu gebucht werden kann, so in der Art eines require("") oder "using".

                  Christian

                  OliverIOO Offline
                  OliverIOO Offline
                  OliverIO
                  schrieb am zuletzt editiert von
                  #8

                  @familienvater

                  Ich verstehe nicht warum du immer das Beispiel mit getstate bringst.
                  Ich glaube wir sind uns einig das pollen schlecht ist.

                  Lese die Doku zum on Befehls des JavaScript Adapters den du ja im Beispiel selbst schon verwendet hast.
                  Das ist genau die Ereignis gesteuerte Funktion die du brauchst und da brauchst du keinen weiteren Cache Mechanismus dazwischen.
                  Mit dem iobroker und JavaScript gibt es ja nur die 2 Möglichkeiten um an die Informationen eines datenpunkts zu kommen:
                  Getstate und der on trigger
                  Und die musst du in der Basis ja auch verwenden.

                  Aber probiere aus, mach Performance Messungen und präsentiere uns deine Ergebnisse

                  Meine Adapter und Widgets
                  TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
                  Links im Profil

                  F 1 Antwort Letzte Antwort
                  0
                  • OliverIOO OliverIO

                    @familienvater

                    Ich verstehe nicht warum du immer das Beispiel mit getstate bringst.
                    Ich glaube wir sind uns einig das pollen schlecht ist.

                    Lese die Doku zum on Befehls des JavaScript Adapters den du ja im Beispiel selbst schon verwendet hast.
                    Das ist genau die Ereignis gesteuerte Funktion die du brauchst und da brauchst du keinen weiteren Cache Mechanismus dazwischen.
                    Mit dem iobroker und JavaScript gibt es ja nur die 2 Möglichkeiten um an die Informationen eines datenpunkts zu kommen:
                    Getstate und der on trigger
                    Und die musst du in der Basis ja auch verwenden.

                    Aber probiere aus, mach Performance Messungen und präsentiere uns deine Ergebnisse

                    F Offline
                    F Offline
                    Familienvater
                    schrieb am zuletzt editiert von
                    #9

                    @oliverio
                    Dann zu meiner ganz ursprünglichen Frage:

                    Wie müsste die "MagicFunction" aussehen, um das als zwei-Zeiler funktionierend zu initialisieren?

                    const idFernseherAn = 'adapter.instanz.bla.blub';
                    let FernseherAn = MagicFunction(idFernseherAn, FernseherAn); 
                    // return der Function ist der initiale getState, und die MagicFunction registriert 
                    // die on-Subscription für den Datenpunkt, und "erstellt" die Callback-Function so, 
                    // das die übergebene Variable als Referenz aktuell gehalten wird, wenn sich der zugrundeliegende Datenpunkt ändert
                    
                    

                    Christian

                    1 Antwort Letzte Antwort
                    0
                    • OliverIOO Offline
                      OliverIOO Offline
                      OliverIO
                      schrieb am zuletzt editiert von OliverIO
                      #10

                      @familienvater
                      Die hätte eine ähnliche Signatur wie die on Funktion
                      Je nachdem was dir lieber ist kannst du direkt eine callback Funktion mit übergeben oder die gibt ein promise zurück, damit du auf datenänderungen neben deinem caching auch reagieren kannst.
                      Zusätzlich würde ich auch eine unsubscribe Funktion schreiben, damit man das on für bestimmte datenpunkte wieder abmelden kann

                      Meine Adapter und Widgets
                      TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
                      Links im Profil

                      F 1 Antwort Letzte Antwort
                      0
                      • OliverIOO OliverIO

                        @familienvater
                        Die hätte eine ähnliche Signatur wie die on Funktion
                        Je nachdem was dir lieber ist kannst du direkt eine callback Funktion mit übergeben oder die gibt ein promise zurück, damit du auf datenänderungen neben deinem caching auch reagieren kannst.
                        Zusätzlich würde ich auch eine unsubscribe Funktion schreiben, damit man das on für bestimmte datenpunkte wieder abmelden kann

                        F Offline
                        F Offline
                        Familienvater
                        schrieb am zuletzt editiert von
                        #11

                        @oliverio

                        Ich habe inzwischen eine funktionierende "SmarteVariablen"-TypeScript-Klasse, die wohl das tut, was ich möchte.

                        Langsam ahne ich aber evtl., was Du mit "doppelt gemoppelt" meintest, verstehe es mangels fehlender/nicht gefundener Dokumentation aber nicht.
                        Es gibt eine Option im Javascript-Adapter:

                        Nicht alle Zustände beim Start abonnieren

                        Leider finde ich keine Hinweise darauf, was diese Option bewirkt, aus das das Auswählen syncrone getState() "verhindert", und man dann alles mit await getStateAsync() machen muss, weil eben nicht alle States beim Start abonniert werden, aber getStateAsync ist z.B. in der Adapter-Doku gar nicht vorhanden, das muss man sich im Forum googlen, anderes Thema...

                        Welche "alle States" abonnieren? Alle States im ganzen ioBroker? Alle in dieser JavaScript-Instanz mit getState angesprochenen Datenpunkte?

                        I bims total verwirrt...

                        Christian

                        paul53P 1 Antwort Letzte Antwort
                        0
                        • F Familienvater

                          @oliverio

                          Ich habe inzwischen eine funktionierende "SmarteVariablen"-TypeScript-Klasse, die wohl das tut, was ich möchte.

                          Langsam ahne ich aber evtl., was Du mit "doppelt gemoppelt" meintest, verstehe es mangels fehlender/nicht gefundener Dokumentation aber nicht.
                          Es gibt eine Option im Javascript-Adapter:

                          Nicht alle Zustände beim Start abonnieren

                          Leider finde ich keine Hinweise darauf, was diese Option bewirkt, aus das das Auswählen syncrone getState() "verhindert", und man dann alles mit await getStateAsync() machen muss, weil eben nicht alle States beim Start abonniert werden, aber getStateAsync ist z.B. in der Adapter-Doku gar nicht vorhanden, das muss man sich im Forum googlen, anderes Thema...

                          Welche "alle States" abonnieren? Alle States im ganzen ioBroker? Alle in dieser JavaScript-Instanz mit getState angesprochenen Datenpunkte?

                          I bims total verwirrt...

                          Christian

                          paul53P Offline
                          paul53P Offline
                          paul53
                          schrieb am zuletzt editiert von paul53
                          #12

                          @familienvater sagte: Welche "alle States" abonnieren? Alle States im ganzen ioBroker?

                          Ja, alle ioBroker-States und -Objekte werden in den Puffer der Javascript-Instanz geladen.
                          Mit der asynchronen Version von getState() werden die Daten vom js-controller geholt.

                          Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
                          Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

                          F 1 Antwort Letzte Antwort
                          0
                          • paul53P paul53

                            @familienvater sagte: Welche "alle States" abonnieren? Alle States im ganzen ioBroker?

                            Ja, alle ioBroker-States und -Objekte werden in den Puffer der Javascript-Instanz geladen.
                            Mit der asynchronen Version von getState() werden die Daten vom js-controller geholt.

                            F Offline
                            F Offline
                            Familienvater
                            schrieb am zuletzt editiert von
                            #13

                            @paul53 sagte in Zykl. getState-Aufrufe vs. eigenes "Cache-Dictionary":

                            Ja, alle ioBroker-States und -Objekte werden in den Puffer der Javascript-Instanz geladen.

                            und wie der Name/die Beschreibung der Option sagt, wahrscheinlich auch entsprechend alle im Java-Adapter abonniert.

                            Dann ist also ein Zugriff via syncronem getState im javaScript-Adapter ein Zugriff auf einen "State-Cache" im Adapter selber?

                            Blöde Frage:
                            Ist es bei einem subscribe() aus einem JS/TS-Sourcefile dann theoretisch egal, ob die "Nicht alle Zustände beim Start abonnieren"-Option ausgewählt ist oder nicht, weil da auf jeden Fall eine Subscription beim js-Controller selber gemacht wird, oder wird das ggf. auch aus dem vom Adapter selbst "vorhandenen" Abonnement vom JS-Adapter wieder an die Subscriptions in den Sourcefiles "multipliziert"?

                            Danke,
                            Christian

                            OliverIOO paul53P 2 Antworten Letzte Antwort
                            0
                            • F Familienvater

                              @paul53 sagte in Zykl. getState-Aufrufe vs. eigenes "Cache-Dictionary":

                              Ja, alle ioBroker-States und -Objekte werden in den Puffer der Javascript-Instanz geladen.

                              und wie der Name/die Beschreibung der Option sagt, wahrscheinlich auch entsprechend alle im Java-Adapter abonniert.

                              Dann ist also ein Zugriff via syncronem getState im javaScript-Adapter ein Zugriff auf einen "State-Cache" im Adapter selber?

                              Blöde Frage:
                              Ist es bei einem subscribe() aus einem JS/TS-Sourcefile dann theoretisch egal, ob die "Nicht alle Zustände beim Start abonnieren"-Option ausgewählt ist oder nicht, weil da auf jeden Fall eine Subscription beim js-Controller selber gemacht wird, oder wird das ggf. auch aus dem vom Adapter selbst "vorhandenen" Abonnement vom JS-Adapter wieder an die Subscriptions in den Sourcefiles "multipliziert"?

                              Danke,
                              Christian

                              OliverIOO Offline
                              OliverIOO Offline
                              OliverIO
                              schrieb am zuletzt editiert von OliverIO
                              #14

                              @familienvater

                              ja. ist egal.
                              getState ist die direkte Entsprechung eines Befehls des iobrokers, welcher der javascript-adapter ausführt. wenn alle dps abonniert sind, ist der wert dann schon im javascript adapter zwischengespeichert. wahrscheinlich spart man sich wartezeit, falls der rechner anderweitig schon ausgelastet ist.
                              auch das abonnieren aller datenpunkte ist ebenfalls so ein caching, welches der javascriptadapter macht.

                              es gab früher mal einen reiter, der wirklich alle ereignisse zu im browser datenpunktänderungen angezeigt hat. das hat aber den browser bzw. nur den tab schnell zur unbenutzbarkeit gebracht. ich denke er wurde deswegen aus iobroker entfernt

                              hast du den mal performancetests gemacht? da müsste man das messen können, auch wenn es nur wenige millisekunden sind

                              ich habe mal auf die schnelle einen test gemacht, aber mit und ohne alle abonnieren nicht viel unterschied festgestellt
                              es könnte natürlich sein, das der getstate befehl von der option nicht abhängt sondern immer bei iobroker nachfragt.
                              die abfrage hat bei mir immer zwischen 7 und 9 sekunden gedauert, egal ob die option aktiviert war oder nicht.
                              kann auch sein dass ich da noch ein denkfehler drin habe, aber await wartet ja immer bis der befehl abgeschlossen ist bevor dann der nächste dran ist.

                              async function test() {
                                  var start=new Date();
                                  for (var i=0;i<10000;i++) {
                                      var x = await getStateAsync("0_userdata.0.test1");
                                  }
                                  var end=new Date();
                                  console.log(start);
                                  console.log(end);
                              }
                              
                              test();
                              

                              Meine Adapter und Widgets
                              TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
                              Links im Profil

                              F 1 Antwort Letzte Antwort
                              0
                              • F Familienvater

                                @paul53 sagte in Zykl. getState-Aufrufe vs. eigenes "Cache-Dictionary":

                                Ja, alle ioBroker-States und -Objekte werden in den Puffer der Javascript-Instanz geladen.

                                und wie der Name/die Beschreibung der Option sagt, wahrscheinlich auch entsprechend alle im Java-Adapter abonniert.

                                Dann ist also ein Zugriff via syncronem getState im javaScript-Adapter ein Zugriff auf einen "State-Cache" im Adapter selber?

                                Blöde Frage:
                                Ist es bei einem subscribe() aus einem JS/TS-Sourcefile dann theoretisch egal, ob die "Nicht alle Zustände beim Start abonnieren"-Option ausgewählt ist oder nicht, weil da auf jeden Fall eine Subscription beim js-Controller selber gemacht wird, oder wird das ggf. auch aus dem vom Adapter selbst "vorhandenen" Abonnement vom JS-Adapter wieder an die Subscriptions in den Sourcefiles "multipliziert"?

                                Danke,
                                Christian

                                paul53P Offline
                                paul53P Offline
                                paul53
                                schrieb am zuletzt editiert von paul53
                                #15

                                @familienvater sagte: Dann ist also ein Zugriff via syncronem getState im javaScript-Adapter ein Zugriff auf einen "State-Cache" im Adapter selber?

                                Ja.

                                @familienvater sagte in Zykl. getState-Aufrufe vs. eigenes "Cache-Dictionary":

                                Ist es bei einem subscribe() aus einem JS/TS-Sourcefile dann theoretisch egal, ob die "Nicht alle Zustände beim Start abonnieren"-Option ausgewählt ist oder nicht, weil da auf jeden Fall eine Subscription beim js-Controller selber gemacht wird

                                Ja, Subscriptions verwenden nicht den internen Puffer.

                                Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
                                Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

                                1 Antwort Letzte Antwort
                                0
                                • OliverIOO OliverIO

                                  @familienvater

                                  ja. ist egal.
                                  getState ist die direkte Entsprechung eines Befehls des iobrokers, welcher der javascript-adapter ausführt. wenn alle dps abonniert sind, ist der wert dann schon im javascript adapter zwischengespeichert. wahrscheinlich spart man sich wartezeit, falls der rechner anderweitig schon ausgelastet ist.
                                  auch das abonnieren aller datenpunkte ist ebenfalls so ein caching, welches der javascriptadapter macht.

                                  es gab früher mal einen reiter, der wirklich alle ereignisse zu im browser datenpunktänderungen angezeigt hat. das hat aber den browser bzw. nur den tab schnell zur unbenutzbarkeit gebracht. ich denke er wurde deswegen aus iobroker entfernt

                                  hast du den mal performancetests gemacht? da müsste man das messen können, auch wenn es nur wenige millisekunden sind

                                  ich habe mal auf die schnelle einen test gemacht, aber mit und ohne alle abonnieren nicht viel unterschied festgestellt
                                  es könnte natürlich sein, das der getstate befehl von der option nicht abhängt sondern immer bei iobroker nachfragt.
                                  die abfrage hat bei mir immer zwischen 7 und 9 sekunden gedauert, egal ob die option aktiviert war oder nicht.
                                  kann auch sein dass ich da noch ein denkfehler drin habe, aber await wartet ja immer bis der befehl abgeschlossen ist bevor dann der nächste dran ist.

                                  async function test() {
                                      var start=new Date();
                                      for (var i=0;i<10000;i++) {
                                          var x = await getStateAsync("0_userdata.0.test1");
                                      }
                                      var end=new Date();
                                      console.log(start);
                                      console.log(end);
                                  }
                                  
                                  test();
                                  
                                  F Offline
                                  F Offline
                                  Familienvater
                                  schrieb am zuletzt editiert von
                                  #16

                                  @oliverio

                                  Hi,

                                  nein, ich habe noch nicht auf Performance getestet, auch weil mir offensichtlich die Basics noch nicht klar waren, und es damit Garbage In => Garbage Out wäre.

                                  @oliverio sagte in Zykl. getState-Aufrufe vs. eigenes "Cache-Dictionary":

                                  kann auch sein dass ich da noch ein denkfehler drin habe, aber await wartet ja immer bis der befehl abgeschlossen ist bevor dann der nächste dran ist
                                  Denkfehler könnte sein, ich denke, mit dem getStateAsync ist es "egal", welche Option gewählt ist, das wird immer an den JS-Controller durchgestochen, wenn ich es richtig verstanden habe.
                                  Man müsste also wahrscheinlich ein normales syncrones getState im "cachenden" Modus gegen ein asyncrones im nicht-Cachenden Modus vergleichen (und dann sollte das syncrone schneller sein, eigentlich).

                                  Und eigentlich müsste man dann schauen, wie viel Zeit die reine Benachrichtigung über die Subscription nach einem "setState" braucht, um eine Aussage zu treffen, ob das Konstrukt mit "abonnierten" Änderungen abbilden auf Variablen CPU-Zyklen-schonender ist als zyklische getStates, und bei welcher Änderungshäufigkeit der BreakEven liegt. Ändert sich der "beobachtete" Datenpunkt häufiger, als er in einer zyklischen Routine abgefragt wird, erzeugt die häufiger triggernde Subscription evtl. mehr Overhead.
                                  Aber ich gehe ja davon aus, das sich z.B. meine "Switches", die ich zyklisch Abfrage, nicht wirklich häufig ändern, sondern fast statisch verhalten.
                                  Aber da kommt mir eine Idee, ich kann ja noch eine Statistk in die Klasse einbauen, die trackt, wie oft der Wert "gelesen" wurde, und wie oft die Subscription getriggert hat, und daraus kann ein "Cache-Hit-Ratio" für den Wert ermitteln, und ggf. Hinweise bei Tageswechsel oder so ins Log schreiben, das dieser Wert evtl. besser jedesmal neu abgefragt wird, und dafür zig unnötige Änderungen über den Trigger eingespart werden könnten.

                                  Bleibt auf jeden Fall spannend das Thema,
                                  Christian

                                  1 Antwort Letzte Antwort
                                  0
                                  • F Offline
                                    F Offline
                                    Familienvater
                                    schrieb am zuletzt editiert von
                                    #17

                                    Also, ich habe mal getestet, und zwar so:

                                    async function test_async() {
                                        var start=Date.now();
                                        var i=0;
                                        for (i=0;i<50000;i++) {
                                            var x = (await getStateAsync("0_userdata.0.test1")).val;
                                        }
                                        var end=Date.now();
                                        console.log(i+".loops with async getState, delta " + (end-start) + "ms");
                                    }
                                    function test_sync() {
                                        var start=Date.now();
                                        var i=0;
                                        for (i=0;i<50000;i++) {
                                            var x = getState("0_userdata.0.test1").val;
                                        }
                                        var end=Date.now();
                                        console.log(i+".loops with sync getState, delta " + (end-start) + "ms");
                                    }
                                     
                                    test_async();
                                    test_sync();
                                    
                                    21:01:42.991	info	javascript.0 (320155) script.js.Logik.PerformanceTests: 50000.loops with sync getState, delta 12ms
                                    21:01:42.991	info	javascript.0 (320155) script.js.Logik.PerformanceTests: registered 2 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
                                    21:01:46.748	info	javascript.0 (320155) script.js.Logik.PerformanceTests: 50000.loops with async getState, delta 3769ms
                                    

                                    Also getState ist "definitv" gecached, und deutlich schneller...
                                    Falls Du Dich wegen der Speed bei mir grundsätzlich wunderst, ioBroker läuft in einer VM mit 2 vCPUs, allerdings ist das ein hochdrehender 6-Core Workstation-XEON mit 3,7GHz (Basis) Takt...

                                    Aber zum "Profilen" der Subscription habe ich nicht wirklich eine Idee, evtl. ein PingPong-Messung(Zeitstempel vor setState auf Id1, in der Subscription von Id1 wird Id2 geändert und in Subscription von Id2 wieder Id1, und Id2 macht das nur 1000x oder so und ermittelt dann das Delta, und evtl. könnte man dann mit dem delta/2 sagen, wie lange ein setState mit trigger dauert?

                                    Muss ich mal testen :-)
                                    Und dann könnte es interessant werden, das ganze in einer mit und einer ohne State-Cache-Instanz zu machen

                                    Christian

                                    F 1 Antwort Letzte Antwort
                                    0
                                    • F Familienvater

                                      Also, ich habe mal getestet, und zwar so:

                                      async function test_async() {
                                          var start=Date.now();
                                          var i=0;
                                          for (i=0;i<50000;i++) {
                                              var x = (await getStateAsync("0_userdata.0.test1")).val;
                                          }
                                          var end=Date.now();
                                          console.log(i+".loops with async getState, delta " + (end-start) + "ms");
                                      }
                                      function test_sync() {
                                          var start=Date.now();
                                          var i=0;
                                          for (i=0;i<50000;i++) {
                                              var x = getState("0_userdata.0.test1").val;
                                          }
                                          var end=Date.now();
                                          console.log(i+".loops with sync getState, delta " + (end-start) + "ms");
                                      }
                                       
                                      test_async();
                                      test_sync();
                                      
                                      21:01:42.991	info	javascript.0 (320155) script.js.Logik.PerformanceTests: 50000.loops with sync getState, delta 12ms
                                      21:01:42.991	info	javascript.0 (320155) script.js.Logik.PerformanceTests: registered 2 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
                                      21:01:46.748	info	javascript.0 (320155) script.js.Logik.PerformanceTests: 50000.loops with async getState, delta 3769ms
                                      

                                      Also getState ist "definitv" gecached, und deutlich schneller...
                                      Falls Du Dich wegen der Speed bei mir grundsätzlich wunderst, ioBroker läuft in einer VM mit 2 vCPUs, allerdings ist das ein hochdrehender 6-Core Workstation-XEON mit 3,7GHz (Basis) Takt...

                                      Aber zum "Profilen" der Subscription habe ich nicht wirklich eine Idee, evtl. ein PingPong-Messung(Zeitstempel vor setState auf Id1, in der Subscription von Id1 wird Id2 geändert und in Subscription von Id2 wieder Id1, und Id2 macht das nur 1000x oder so und ermittelt dann das Delta, und evtl. könnte man dann mit dem delta/2 sagen, wie lange ein setState mit trigger dauert?

                                      Muss ich mal testen :-)
                                      Und dann könnte es interessant werden, das ganze in einer mit und einer ohne State-Cache-Instanz zu machen

                                      Christian

                                      F Offline
                                      F Offline
                                      Familienvater
                                      schrieb am zuletzt editiert von
                                      #18

                                      Ich bin selbst leicht "erstaunt", das es funktioniert, weil eigentlich darf die gecachte Instanz nur die default 1000 setState pro Minute triggern, aber der callback in den subscriptions läßt sich evtl. nicht auf die zurückverfolgen, oder ist so schnell rum, das noch kein Limiter anspricht?
                                      Und weil ich es in meiner "leeren" Instanz.1 getestet habe, läuft da auch sonst gar nix

                                      "use strict";
                                      
                                      const loops=5000;
                                      let start=0;
                                      let end=0;
                                      
                                      async function test_asyncStartPingPong() {
                                      
                                          // short delay, to let everything register...
                                          await new Promise(r => setTimeout(r, 2000));
                                          console.log("Start "+loops+".loops PingPong now!");
                                      
                                          start=Date.now();
                                          // start ping pong
                                          await setStateAsync('0_userdata.0.test1',loops);
                                      }
                                      
                                      on({id: '0_userdata.0.test1', change:'any'}, 
                                      function (obj) {
                                          setState('0_userdata.0.test2', obj.state.val-1);
                                      });
                                      
                                      on({id: '0_userdata.0.test2', change:'any'}, 
                                      function (obj) {
                                          if (obj.state.val>0)
                                              setState('0_userdata.0.test1', obj.state.val-1);
                                          else
                                          {
                                              end=Date.now();
                                              console.log(loops+".loops PingPong, received .val "+obj.state.val+" in " + obj.id + ", delta " + (end-start) + "ms");
                                          }
                                      });
                                      
                                      test_asyncStartPingPong();
                                      

                                      Ohne "Caching" geht gar nix, obwohl in meinem Script keine getStates sind, werden welche angemosert, und globale/common Files habe ich keine expliziten in Instanz.1. Und die Werte schwanken "stark", der erste Wert ist direkt nach dem ich die Instanz neu gestartet habe, da ist die aber im Hintergrund evtl. noch dabei, den Cache zu füllen, nach 5 min Wartezeit ist das ganze 10x schneller, dann sogar nochmal etwas schneller, und dann ist es deutlich langsamer, da kann halt auch noch sonstwas auf dem ioBroker los sein, oder auch die anderen VMs auf dem esxi könnten "sonstwas" treiben...

                                      21:59:15.800	info	javascript.1 (327919) Start javascript script.js.TestInstanz1.PerformanceTests
                                      21:59:15.813	info	javascript.1 (327919) script.js.TestInstanz1.PerformanceTests: registered 4 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
                                      21:59:17.813	info	javascript.1 (327919) script.js.TestInstanz1.PerformanceTests: Start 5000.loops PingPong now!
                                      22:00:00.194	info	javascript.1 (327919) script.js.TestInstanz1.PerformanceTests: 5000.loops PingPong, received .val -1 in 0_userdata.0.test2, delta 42380ms
                                      22:05:12.407	info	javascript.0 (327870) Stop script script.js.TestInstanz1.PerformanceTests
                                      22:05:12.413	info	javascript.1 (327919) Stop script script.js.TestInstanz1.PerformanceTests
                                      22:05:12.416	info	javascript.1 (327919) Start javascript script.js.TestInstanz1.PerformanceTests
                                      22:05:12.422	info	javascript.1 (327919) script.js.TestInstanz1.PerformanceTests: registered 4 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
                                      22:05:14.422	info	javascript.1 (327919) script.js.TestInstanz1.PerformanceTests: Start 5000.loops PingPong now!
                                      22:05:19.332	info	javascript.1 (327919) script.js.TestInstanz1.PerformanceTests: 5000.loops PingPong, received .val -1 in 0_userdata.0.test2, delta 4910ms
                                      22:05:42.881	info	javascript.0 (327870) Stop script script.js.TestInstanz1.PerformanceTests
                                      22:05:42.885	info	javascript.1 (327919) Stop script script.js.TestInstanz1.PerformanceTests
                                      22:05:42.931	info	javascript.1 (327919) Start javascript script.js.TestInstanz1.PerformanceTests
                                      22:05:42.934	info	javascript.1 (327919) script.js.TestInstanz1.PerformanceTests: registered 4 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
                                      22:05:44.934	info	javascript.1 (327919) script.js.TestInstanz1.PerformanceTests: Start 5000.loops PingPong now!
                                      22:05:49.415	info	javascript.1 (327919) script.js.TestInstanz1.PerformanceTests: 5000.loops PingPong, received .val -1 in 0_userdata.0.test2, delta 4481ms
                                      22:06:04.647	info	javascript.1 (327919) Stop script script.js.TestInstanz1.PerformanceTests
                                      22:06:04.646	info	javascript.0 (327870) Stop script script.js.TestInstanz1.PerformanceTests
                                      22:06:04.650	info	javascript.1 (327919) Start javascript script.js.TestInstanz1.PerformanceTests
                                      22:06:04.653	info	javascript.1 (327919) script.js.TestInstanz1.PerformanceTests: registered 4 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
                                      22:06:06.653	info	javascript.1 (327919) script.js.TestInstanz1.PerformanceTests: Start 5000.loops PingPong now!
                                      22:06:17.941	info	javascript.1 (327919) script.js.TestInstanz1.PerformanceTests: 5000.loops PingPong, received .val -1 in 0_userdata.0.test2, delta 11287ms
                                      

                                      Ich danke, man kann so eine ungefähre Aussage zur RoundTrip-Zeit machen, im Optimalfall ist es ca. 1 ms, die es vom setState bis zur Ankunft im subscribe-Callback braucht (auf meinem 3,7GHz-Xeon).

                                      Christian

                                      1 Antwort Letzte Antwort
                                      0
                                      Antworten
                                      • In einem neuen Thema antworten
                                      Anmelden zum Antworten
                                      • Älteste zuerst
                                      • Neuste zuerst
                                      • Meiste Stimmen


                                      Support us

                                      ioBroker
                                      Community Adapters
                                      Donate

                                      882

                                      Online

                                      32.4k

                                      Benutzer

                                      81.5k

                                      Themen

                                      1.3m

                                      Beiträge
                                      Community
                                      Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                                      ioBroker Community 2014-2025
                                      logo
                                      • Anmelden

                                      • Du hast noch kein Konto? Registrieren

                                      • Anmelden oder registrieren, um zu suchen
                                      • Erster Beitrag
                                        Letzter Beitrag
                                      0
                                      • Home
                                      • Aktuell
                                      • Tags
                                      • Ungelesen 0
                                      • Kategorien
                                      • Unreplied
                                      • Beliebt
                                      • GitHub
                                      • Docu
                                      • Hilfe