Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. Probleme getHistory im History Adapter v3.0.1- Invalid call

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    Probleme getHistory im History Adapter v3.0.1- Invalid call

    This topic has been deleted. Only users with topic management privileges can see it.
    • G
      Gismoh last edited by

      Hallo zusammen,

      ich habe Probleme, die getHistory-Funktion des History Adapters in meinen Javascript-Skripten zu verwenden. Egal welche Optionen ich übergebe, ich erhalte immer den Fehler:

      Fehler beim Aufruf von getHistory für <Datenpunkt-ID>: Invalid call. No options for getHistory provided
      

      Meine Systeminformationen:

      Betriebssystem: Linux
      Plattform: linux
      Architektur: x64
      Node.js: v20.18.3
      NPM: 10.8.2
      js-controller: 7.0.6
      History Adapter Versionen getestet: 3.0.1 (aktuell), 3.0.0, 2.2.6

      Meine history.0-Adapter Konfiguration:
      Ich verwende die Standardkonfiguration, hier wurden keine Anpassungen vorgenommen.

      Mein Testskript:

      async function erstelleUndLoggeTestDatenpunkt() {
        const testDpId = '0_userdata.0.testVerlaufDp';
      
        // Erstelle den Datenpunkt, falls er noch nicht existiert
        const existiert = await existsStateAsync(testDpId);
        if (!existiert) {
          await createStateAsync(testDpId, 0, {
            name: 'Test Verlauf Datenpunkt',
            type: 'number',
            role: 'state',
            read: true,
            write: true,
          });
          log(`Datenpunkt ${testDpId} wurde erstellt.`);
        }
      
        // Protokolliere einige Werte mit Zeitstempeln
        const jetzt = Date.now();
        await setStateAsync(testDpId, 10, false, jetzt - 60000);
        await setStateAsync(testDpId, 20, false, jetzt - 30000);
        await setStateAsync(testDpId, 30, true, jetzt);
      
        log('Rufe leseTestVerlauf auf...');
      
        // Versuchen wir nun, den Verlauf dieses Datenpunkts abzurufen
        await leseTestVerlauf(testDpId);
      }
      
      async function leseTestVerlauf(dpId) {
        log('Testausgabe leseTestVerlauf');
        const historyInstanz = 'history.0';
        const jetzt = Date.now();
        const startZeit = jetzt - 120000; // Lese Verlauf der letzten zwei Minuten
        const endZeit = jetzt;
      
        const optionen = {
          start: startZeit,
          end: endZeit,
          aggregate: 'none',
          addId: true,
          returnNewestEntries: false,
        };
      
        log(`Versuche Verlauf für ${dpId} abzurufen...`);
        log(`Sende an ${historyInstanz} 'getHistory' mit Optionen: ${JSON.stringify({ id: dpId, ...optionen })}`);
        try {
          const verlaufsDaten = await sendToAsync(historyInstanz, 'getHistory', { id: dpId, ...optionen });
          log(`Verlaufsdaten (raw) für ${dpId}: ${JSON.stringify(verlaufsDaten)}`);
          if (verlaufsDaten && verlaufsDaten.result) {
            log(`Verlaufsdaten für ${dpId}: ${JSON.stringify(verlaufsDaten.result)}`);
          } else {
            log(`Fehler beim Abrufen der Verlaufsdaten für ${dpId}: ${JSON.stringify(verlaufsDaten)}`, 'warn');
          }
        } catch (e) {
          log(`Fehler beim Aufruf von getHistory für ${dpId}: ${e}`, 'error');
        }
      }
      
      erstelleUndLoggeTestDatenpunkt();
      

      Log-Ausschnitte (Beispielhaft mit Version 3.0.1 - ähnliche Ausgabe mit anderen Versionen):

      javascript.0  info Start JavaScript script.js.Test.Akku-Skript-11_Test_001 (Javascript/js)
      javascript.0  info script.js.Test.Akku-Skript-11_Test_001: Rufe leseTestVerlauf auf...
      javascript.0  info script.js.Test.Akku-Skript-11_Test_001: Testausgabe leseTestVerlauf
      javascript.0  info script.js.Test.Akku-Skript-11_Test_001: Versuche Verlauf für 0_userdata.0.testVerlaufDp abzurufen...
      javascript.0  info script.js.Test.Akku-Skript-11_Test_001: Sende an history.0 'getHistory' mit Optionen: {"id":"0_userdata.0.testVerlaufDp","start":1746363867548,"end":1746363987548,"aggregate":"none","addId":true,"returnNewestEntries":false}
      javascript.0 error script.js.Test.Akku-Skript-11_Test_001: Fehler beim Aufruf von getHistory für 0_userdata.0.testVerlaufDp: Invalid call. No options for getHistory provided
      history.0     debug Value logged 0_userdata.0.testVerlaufDp, value=30, ts=1746363987545
      history.0     debug new value received for 0_userdata.0.testVerlaufDp, new-value=30, ts=1746363987545, relog=false
      history.0     debug Value logged 0_userdata.0.testVerlaufDp, value=20, ts=1746363987542
      history.0     debug new value received for 0_userdata.0.testVerlaufDp, new-value=20, ts=1746363987542, relog=false
      history.0     debug Value logged 0_userdata.0.testVerlaufDp, value=10, ts=1746363987454
      history.0     debug new value received for 0_userdata.0.testVerlaufDp, new-value=10, ts=1746363987454, relog=false
      

      Wie man sieht, werden die Optionen im Log korrekt ausgegeben, aber der history-Adapter meldet trotzdem einen "Invalid call". Die grundlegende Protokollierung von Werten durch den Adapter funktioniert jedoch.

      Ich habe bereits verschiedene Versionen des Adapters (3.0.1, 3.0.0, 2.2.6) getestet, aber das Problem bleibt bestehen.

      Hat jemand eine Idee, woran das liegen könnte oder wie ich das Problem weiter eingrenzen kann? Gibt es möglicherweise eine spezielle Konfiguration oder eine andere Interaktion, die hier eine Rolle spielt?

      Vielen Dank für eure Hilfe!

      Thomas Braun paul53 Homoran 3 Replies Last reply Reply Quote 0
      • Thomas Braun
        Thomas Braun Most Active @Gismoh last edited by

        @gismoh sagte in Probleme getHistory im History Adapter v3.0.1- Invalid call:

        Node.js: v20.18.3

        Hat zwar nichts mit deinem Problem zu tun, nodejs muss aber aktualisiert werden.
        Der Rest vom OS dann vermutlich auch, läuft das doch über den gleichen Mechanismus.

        1 Reply Last reply Reply Quote 0
        • paul53
          paul53 @Gismoh last edited by paul53

          @gismoh sagte:

              const verlaufsDaten = await sendToAsync(historyInstanz, 'getHistory', { id: dpId, ...optionen });
          

          Sieht die Zeile wirklich so aus (mit den 3 Punkten vor optionen)?
          Was soll in Zeilen 19 bis 21 mit jetzt passieren?
          Zeitstempel übergibt man so:

            await setStateAsync(testDpId, {val: 10, ack: false, ts: jetzt - 60000});
          
          G 1 Reply Last reply Reply Quote 0
          • Homoran
            Homoran Global Moderator Administrators @Gismoh last edited by

            @gismoh sagte in Probleme getHistory im History Adapter v3.0.1- Invalid call:

            aber der history-Adapter meldet trotzdem einen "Invalid call".

            nein!

            @gismoh sagte in Probleme getHistory im History Adapter v3.0.1- Invalid call:

            javascript.0 error script.js.Test.Akku-Skript-11_Test_001: Fehler beim Aufruf von getHistor

            der Javascript Adapter meldet einen falschen Aufruf!

            sieh dir @paul53 Hinweise an

            1 Reply Last reply Reply Quote 0
            • G
              Gismoh @paul53 last edited by

              @paul53
              Hallo nochmal!

              Vielen Dank für deine Hinweise und die Erklärung zur Zeitstempelübergabe.

              Leider hat auch das explizite Übergeben der einzelnen Optionen ohne den Spread-Operator nicht zu einer Änderung des Ergebnisses geführt.

              Fehler beim Aufruf von getHistory für <Datenpunkt-ID>: Invalid call. No options for getHistory provided
              

              Aktuell:
              Node.js: v20.19.1
              NPM: 10.8.2
              js-controller: 7.0.6

              async function erstelleUndLoggeTestDatenpunkt() {
                const testDpId = '0_userdata.0.testVerlaufDp';
              
                // Erstelle den Datenpunkt, falls er noch nicht existiert
                const existiert = await existsStateAsync(testDpId);
                if (!existiert) {
                  await createStateAsync(testDpId, 0, {
                    name: 'Test Verlauf Datenpunkt',
                    type: 'number',
                    role: 'state',
                    read: true,
                    write: true,
                  });
                  log(`Datenpunkt ${testDpId} wurde erstellt.`);
                }
              
                // Protokolliere einige Werte mit Zeitstempeln
                const jetzt = Date.now();
                await setStateAsync(testDpId, { val: 10, ack: false, ts: jetzt - 60000 }); // Protokolliere Wert 10 vor einer Minute
                await setStateAsync(testDpId, { val: 20, ack: false, ts: jetzt - 30000 }); // Protokolliere Wert 20 vor dreißig Sekunden
                await setStateAsync(testDpId, { val: 30, ack: true, ts: jetzt });        // Protokolliere Wert 30 jetzt
              
                log('Rufe leseTestVerlauf auf...');
              
                // Versuchen wir nun, den Verlauf dieses Datenpunkts abzurufen
                await leseTestVerlauf(testDpId);
              }
              
              async function leseTestVerlauf(dpId) {
                log('Testausgabe leseTestVerlauf');
                const historyInstanz = 'history.0';
                const jetzt = Date.now();
                const startZeit = jetzt - 120000; // Lese Verlauf der letzten zwei Minuten
                const endZeit = jetzt;
              
                const optionen = {
                  start: startZeit,
                  end: endZeit,
                  aggregate: 'none',
                  addId: true,
                  returnNewestEntries: false,
                };
              
                log(`Versuche Verlauf für ${dpId} abzurufen...`);
                log(`Sende an ${historyInstanz} 'getHistory' mit Optionen: ${JSON.stringify({ id: dpId, start: optionen.start, end: optionen.end, aggregate: optionen.aggregate, addId: optionen.addId, returnNewestEntries: optionen.returnNewestEntries })}`);
                try {
                  const verlaufsDaten = await sendToAsync(historyInstanz, 'getHistory', { id: dpId, start: optionen.start, end: optionen.end, aggregate: optionen.aggregate, addId: optionen.addId, returnNewestEntries: optionen.returnNewestEntries });
                  log(`Verlaufsdaten (raw) für ${dpId}: ${JSON.stringify(verlaufsDaten)}`);
                  if (verlaufsDaten && verlaufsDaten.result) {
                    log(`Verlaufsdaten für ${dpId}: ${JSON.stringify(verlaufsDaten.result)}`);
                  } else {
                    log(`Fehler beim Abrufen der Verlaufsdaten für ${dpId}: ${JSON.stringify(verlaufsDaten)}`, 'warn');
                  }
                } catch (e) {
                  log(`Fehler beim Aufruf von getHistory für ${dpId}: ${e}`, 'error');
                }
              }
              
              erstelleUndLoggeTestDatenpunkt();
              

              Ergebnisse:

              Die Übergabe der Optionen an getHistory erfolgte sowohl mit dem Spread-Operator (...optionen - im vorherigen Test) als auch durch die explizite Angabe der einzelnen Eigenschaften ({ id: dpId, start: optionen.start, ... } - im letzten Test). Beide Methoden führten zum gleichen Ergebnis.
              Die Schreibweise für setStateAsync mit dem Objekt { val: ..., ts: ... } wurde verwendet.

              Die grundlegende Protokollierung von Datenpunkten durch den History Adapter funktioniert.
              Trotz dieser Versuche erhalte ich weiterhin den Fehler "Invalid call. No options for getHistory provided". Es scheint, als ob die übergebenen Optionen vom history-Adapter in meiner Umgebung aus irgendeinem Grund nicht akzeptiert werden.

              Hat vielleicht noch jemand eine Idee oder einen Ansatzpunkt, den ich bisher übersehen habe? Ich bin für jede Hilfe dankbar!

              Homoran paul53 2 Replies Last reply Reply Quote 0
              • Homoran
                Homoran Global Moderator Administrators @Gismoh last edited by

                @gismoh sagte in Probleme getHistory im History Adapter v3.0.1- Invalid call:

                Hat vielleicht noch jemand eine Idee

                wie bereits gesagt, kommt die Meldung vom js-Adapter, nicht von History.

                Dementsprechend interpretiere ich die Meldung

                @gismoh sagte in Probleme getHistory im History Adapter v3.0.1- Invalid call:

                Invalid call. No options for getHistory provided"

                so, dass du dem Befehl getHistory notwendige Parameter nicht mitgegeben hast

                G 1 Reply Last reply Reply Quote 1
                • G
                  Gismoh @Homoran last edited by

                  @homoran
                  merci, werde nun testen 😉

                  1 Reply Last reply Reply Quote 0
                  • paul53
                    paul53 @Gismoh last edited by

                    @Gismoh

                    Versuche es mal so, wie es dokumentiert ist.

                        const verlaufsDaten = await sendToAsync(historyInstanz, 'getHistory', { id: dpId, options: optionen});
                    
                    G 1 Reply Last reply Reply Quote 1
                    • G
                      Gismoh @paul53 last edited by Gismoh

                      @paul53, @Homoran

                      Kurzes Update:

                      async function erstelleUndLoggeTestDatenpunkt() {
                        const testDpId = '0_userdata.0.testVerlaufDp';
                      
                        // Erstelle den Datenpunkt, falls er noch nicht existiert
                        const existiert = await existsStateAsync(testDpId);
                        if (!existiert) {
                          await createStateAsync(testDpId, 0, {
                            name: 'Test Verlauf Datenpunkt',
                            type: 'number',
                            role: 'state',
                            read: true,
                            write: true,
                          });
                          log(`Datenpunkt ${testDpId} wurde erstellt.`);
                        }
                      
                        // Protokolliere einige Werte mit Zeitstempeln
                        const jetzt = Date.now();
                        await setStateAsync(testDpId, { val: 10, ack: false, ts: jetzt - 60000 }); // Protokolliere Wert 10 vor einer Minute
                        await setStateAsync(testDpId, { val: 20, ack: false, ts: jetzt - 30000 }); // Protokolliere Wert 20 vor dreißig Sekunden
                        await setStateAsync(testDpId, { val: 30, ack: true, ts: jetzt });        // Protokolliere Wert 30 jetzt
                      
                        log('Rufe leseTestVerlauf auf...');
                      
                        // Versuchen wir nun, den Verlauf dieses Datenpunkts abzurufen
                        await leseTestVerlauf(testDpId);
                      }
                      
                      async function leseTestVerlauf(dpId) {
                        log('Testausgabe leseTestVerlauf');
                        const historyInstanz = 'history.0';
                        const jetzt = Date.now();
                        const startZeit = jetzt - 120000; // Lese Verlauf der letzten zwei Minuten
                        const endZeit = jetzt;
                      
                        const optionen = {
                          start: startZeit,
                          end: endZeit,
                          aggregate: 'none',
                          addId: true,
                          returnNewestEntries: false,
                        };
                      
                        log(`Versuche Verlauf für ${dpId} abzurufen...`);
                        log(`Sende an ${historyInstanz} 'getHistory' mit Optionen (verschachtelt): ${JSON.stringify({ id: dpId, options: optionen })}`);
                        try {
                          const verlaufsDaten = await sendToAsync(historyInstanz, 'getHistory', { id: dpId, options: { ...optionen } });
                          log(`Verlaufsdaten (raw) für ${dpId}: ${JSON.stringify(verlaufsDaten)}`);
                          if (verlaufsDaten && verlaufsDaten.result) {
                            log(`Verlaufsdaten für ${dpId}: ${JSON.stringify(verlaufsDaten.result)}`);
                          } else {
                            log(`Fehler beim Abrufen der Verlaufsdaten für ${dpId}: ${JSON.stringify(verlaufsDaten)}`, 'warn');
                          }
                        } catch (e) {
                          log(`Fehler beim Aufruf von getHistory für ${dpId}: ${e}`, 'error');
                        }
                      }
                      
                      erstelleUndLoggeTestDatenpunkt();
                      

                      Das Problem mit "Invalid call. No options for getHistory provided" ist gelöst! Der Schlüssel war, die Optionen für getHistory im sendToAsync-Aufruf unter der Eigenschaft options zu verschachteln. Dies funktioniert sowohl mit der direkten Übergabe des optionen-Objekts als auch mit dem Spread-Operator:

                      await sendToAsync(historyInstanz, 'getHistory', { id: dpId, options: optionen });
                      

                      oder

                      await sendToAsync(historyInstanz, 'getHistory', { id: dpId, options: { ...optionen } });
                      

                      Der History Adapter erwartet die Optionen in dieser Struktur. Die Abfrage funktioniert nun wie erwartet.
                      Als Nächstes werde ich nun mein ursprüngliches Skript anpassen, um die getHistory-Aufrufe entsprechend zu gestalten.
                      Danke für die Unterstützung!

                      1 Reply Last reply Reply Quote 0
                      • First post
                        Last post

                      Support us

                      ioBroker
                      Community Adapters
                      Donate

                      670
                      Online

                      31.8k
                      Users

                      80.0k
                      Topics

                      1.3m
                      Posts

                      4
                      9
                      233
                      Loading More Posts
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes
                      Reply
                      • Reply as topic
                      Log in to reply
                      Community
                      Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                      The ioBroker Community 2014-2023
                      logo