NEWS
Probleme getHistory im History Adapter v3.0.1- Invalid call
-
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.6Meine 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!
-
@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. -
@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 mitjetzt
passieren?
Zeitstempel übergibt man so:await setStateAsync(testDpId, {val: 10, ack: false, ts: jetzt - 60000});
-
@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
-
@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.6async 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!
-
@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
-
@homoran
merci, werde nun testen -
Versuche es mal so, wie es dokumentiert ist.
const verlaufsDaten = await sendToAsync(historyInstanz, 'getHistory', { id: dpId, options: optionen});
-
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!