NEWS
Helium API per GET abrufen (incl. User-Agent)
-
@stephan-sporbert
du musst dann auch den Befehl verwenden, der es in einen Datenpunkt schreibt.
der datenpunkt muss zuvor angelegt werden. am besten Number
und der datenpunktname dann bei dp anpassen.var dp = "javascript.0.test"; var axios = require("axios"); var v_url = 'https://api.helium.io/v1/hotspots/112gJzabaVykY8hvNgZcgSU2pJ5YkjHi7QUST9i9ugtofoXQfkEc/rewards/sum/?max_time=2029-01-01T00:00:01Z&min_time=2021-01-01T00:00:01Z' async function test() { log((await getData()).total); } async function writeValue() { setState(dp,(await getData()).total); } async function getData() { try { let res = await axios.get(v_url, { headers: { 'User-Agent': 'Mozilla/5.0.' } }); return res.data.data; } catch (e) { log(e) } } //test(); writeValue();
wenn du mehr wie einen Wert schreiben möchtest, dann würde ich dein Skript ebenfalls noch ein wenig anpassen. Da so 3 Anfragen an den Server rausgehen, obwohl du jedesmal die gleichen Daten erhälst
-
@oliverio
Wahnsinn, danke!
mal sehen ob ich das hin bekomme, ich hab noch nie mit Javascript gearbeitet -
var dp1 = "javascript.0.test1"; var dp2 = "javascript.0.test2"; var axios = require("axios"); var v_url = 'https://api.helium.io/v1/hotspots/112gJzabaVykY8hvNgZcgSU2pJ5YkjHi7QUST9i9ugtofoXQfkEc/rewards/sum/?max_time=2029-01-01T00:00:01Z&min_time=2021-01-01T00:00:01Z' async function test() { var data = await getData(); log(data.total); log(data.stddev); } async function writeValue() { var data = await getData(); log(data); setState(dp1,data.total); setState(dp2,data.stddev); } async function getData() { try { let res = await axios.get(v_url, { headers: { 'User-Agent': 'Mozilla/5.0.' } }); return res.data.data; } catch (e) { log(e) } } //test(); writeValue();
-
@oliverio
Klasse, es funktioniert.Ich danke dir von Herzen
wenn ich das jetzt aller 30minausführen will
// Alle 30 Minunten das skript ausführen schedule('*/30 * * * *', javascript.0.test);
oder bin ich absolut auf dem Holzweg?
-
@stephan-sporbert
nicht ganz,
musste selbst nachschauen, da ich kein schedule aktuell verwende und auch nicht mit asyncdas unten angegebene schedule ruft immer zur 0ten und zur 30igsten Minute die Funktion auf. Für andere Werte kannst du den assistenten im Skripteditor verwenden (uhrenicon oben rechts)
müsste aber wie folgt funktionieren
var dp1 = "javascript.0.test1"; var dp2 = "javascript.0.test2"; var axios = require("axios"); var v_url = 'https://api.helium.io/v1/hotspots/112gJzabaVykY8hvNgZcgSU2pJ5YkjHi7QUST9i9ugtofoXQfkEc/rewards/sum/?max_time=2029-01-01T00:00:01Z&min_time=2021-01-01T00:00:01Z' async function writeValue() { var data = await getData(); log(data); setState(dp1,data.total); setState(dp2,data.stddev); } async function getData() { try { let res = await axios.get(v_url, { headers: { 'User-Agent': 'Mozilla/5.0.' } }); return res.data.data; } catch (e) { log(e) } } schedule('*/30 * * * *',function() { writeValue(); });
-
-
Hier lässt sich die API Dokumentation übrigens finden
-
Erstmal vielen Dank für eure Vorarbeit. Das hat mir schon mal weitergeholfen.
Ich möchte gerne die Rewards der letzten 24h, 7 Tage & 30 Tage auslesen und das in das o.g. Skript einbauen.Laut API kann ich das wie folgt abfragen
https://api.helium.io/v1/hotspots/HOTSPOT_ID/rewards/sum/?min_time=-1%20day https://api.helium.io/v1/hotspots/HOTSPOT_ID/rewards/sum/?min_time=-7%20day https://api.helium.io/v1/hotspots/HOTSPOT_ID/rewards/sum/?min_time=-30%20day
Ich könnte das o.g. Skript auch drei mal kopieren und den Link tauschen, aber ich schätze, das geht auch so, dass alle vier Links in einem Skript abgefragt werden, leider habe ich davon keine Ahnung. Kann mir hierbei jemand helfen?
Gruß Markus
-
ich habe dir den code ein wenig umgestellt.
jetzt kannst du einfach die funktion writeValueOverview kopieren
neu einfügen, einen neuen Namen geben und die Parameter
konfigurieren.
Befasse dich mal mit jeder einzelnen Zeile, dann wirst du auch das extrahieren der Daten aus einem JSON-Objekt gut hinbekommen.
Im vorliegenden Beispiel erhälst du ein javascriptobjekt zurück.
dieses objekt hat sogenannte properties oder eigenschaften.
das sind eigentlich nix anderes wie variable, die zusammengefasst sind.
daher kannst du total mit
data.total
und die standardabweichung mit
data.stddev
adressieren.
die struktur ist aber je api aufruf anders und du musst in der doku nachschauen oder, das was da auf der console ausgegeben wird.Problem bei rewards ist, das da eine Liste zurückkommt und nicht ein einzelner Wert
Return the last 7 days of rewards bucketed by day
Was willst du mit der Liste machen?
var axios = require("axios"); async function writeValueOverview() { var dp1 = "javascript.0.test1"; var dp2 = "javascript.0.test2"; var v_url = 'https://api.helium.io/v1/hotspots/112gJzabaVykY8hvNgZcgSU2pJ5YkjHi7QUST9i9ugtofoXQfkEc/rewards/sum/?max_time=2029-01-01T00:00:01Z&min_time=2021-01-01T00:00:01Z' var data = await getData(url); //abruf der daten log(data); // ausgabe des ergebnisses auf der debug-console setState(dp1,data.total); // schreiben der summe in datenpunkt setState(dp2,data.stddev); // schreiben der standardabweichung in datenpunkt } async function writeValueReward1() { var dp1 = "javascript.0.reward1"; var url = 'https://api.helium.io/v1/hotspots/HOTSPOT_ID/rewards/sum/?min_time=-1%20day' var data = await getData(url); //abruf der daten log(data); // ausgabe des ergebnisses auf der debug-console setState(dp1,data.??); // schreiben des rewards in datenpunkt } async function writeValueReward2() { var dp1 = "javascript.0.reward2"; var url = 'https://api.helium.io/v1/hotspots/HOTSPOT_ID/rewards/sum/?min_time=-7%20day' var data = await getData(url); //abruf der daten log(data); // ausgabe des ergebnisses auf der debug-console setState(dp1,data.??); // schreiben des rewards in datenpunk datenpunkt } async function getData(url) { try { let res = await axios.get(url, { headers: { 'User-Agent': 'Mozilla/5.0.' } }); return res.data.data; } catch (e) { log(e) } } schedule('*/30 * * * *',function() { writeValueOverview(); writeValueReward1(); writeValueReward2(); });
-
@oliverio
Vielen Dank.
Im Grunde möchte ich nur vier Datenobjekte mit Daten füttern:-
Walletguthaben
-
HNT letzte 24h
-
HNT letzte 7 Tage
-
HNT letzte 30 Tage
Bei meinen urls nutze ich die Bucketfunktion nicht, sondern bekomme nur eine Zeile wo ich dann den data.total Wert abgreifen kann.
Ich habe gestern ein wenig rum getestet und festgestellt, dass sich das Skript (oder API oder was auch immer ) bei zu vielen gleichzeitigen Abrufen verschluckt und der Wert data.total dann bei einem der Datenpunkte (variiert meist) nicht ausgelesen werden kann. Manchmal geht es gut, und man bekommt alle vier Daten ausgelesen, häufig waren es aber nur 3. Daher habe ich einen Timeout eingebaut. Damit funktioniert es zuverlässig.
Zum Testen habe ich als Basis dein erstes Skript genutzt, aber auch dein zuletzt gepostetes Skript für meine Bedürfnisse angepasst.Skript1
Skript2
Bei beiden funktioniert das Auslesen gut, allerdings bekomme ich jeweils drei Fehlerzeilen angezeigt, die ich (wahrscheinlich aus fehlendem Basiswissen) nicht behoben bekomme:
17.8.2022, 09:48:06.431 [info ]: javascript.0 (1151) Start javascript script.js.Allgemein.Crypto.Helium.TrendyGunmetalHare 17.8.2022, 09:48:06.479 [info ]: javascript.0 (1151) script.js.Allgemein.Crypto.Helium.TrendyGunmetalHare: registered 0 subscriptions and 1 schedule 17.8.2022, 09:48:06.481 [error]: javascript.0 (1151) script.js.Allgemein.Crypto.Helium.TrendyGunmetalHare: ReferenceError: writeValue1 is not defined 17.8.2022, 09:48:06.481 [error]: javascript.0 (1151) at script.js.Allgemein.Crypto.Helium.TrendyGunmetalHare:69:1 17.8.2022, 09:48:06.481 [error]: javascript.0 (1151) at script.js.Allgemein.Crypto.Helium.TrendyGunmetalHare:73:3 17.8.2022, 09:48:07.658 [info ]: javascript.0 (1151) script.js.Allgemein.Crypto.Helium.TrendyGunmetalHare: {'total':1.39006203,'sum':139006203,'stddev':0.0096834757243116,'min':0,'median':0.00827458,'max':0,'avg':0.013113792735849056} 17.8.2022, 09:48:08.582 [info ]: javascript.0 (1151) script.js.Allgemein.Crypto.Helium.TrendyGunmetalHare: {'total':0.02237045,'sum':2237045,'stddev':0.0026280645619987,'min':0,'median':0.00729542,'max':0,'avg':0.007456816666666667} 17.8.2022, 09:48:09.582 [info ]: javascript.0 (1151) script.js.Allgemein.Crypto.Helium.TrendyGunmetalHare: {'total':0.26189041,'sum':26189041,'stddev':0.0094876854151907,'min':0,'median':0.00765452,'max':0,'avg':0.011386539565217391} 17.8.2022, 09:48:10.577 [info ]: javascript.0 (1151) script.js.Allgemein.Crypto.Helium.TrendyGunmetalHare: {'total':0.8288541,'sum':82885410,'stddev':0.0096992973232438,'min':0,'median':0.00748039,'max':0,'avg':0.012558395454545455}
Könntest du mir hierbei nochmal unter die Arme greifen?
Besten Dank -
-
@unbekannt
Probiere es erst Mal.mit meiner LösungDie fehlerm Ladung ist eigentlich selbst erklärend.
Die Funktion mit diesem Namen wurde nie definiert
Die Folgezeilen sind der stacktrace für diesen Fehler -
Wenn ich dein zuletzt gepostetes Skript nutze (plus ergänzend der Timeout), sprich Sktipt2 in meinem letzten Post, dann bekomme ich eine analoge Fehlermeldung:
17.8.2022, 15:17:02.151 [info ]: javascript.0 (1151) Stop script script.js.Allgemein.Crypto.Helium.test 17.8.2022, 15:17:02.255 [info ]: javascript.0 (1151) Start javascript script.js.Allgemein.Crypto.Helium.test 17.8.2022, 15:17:02.291 [info ]: javascript.0 (1151) script.js.Allgemein.Crypto.Helium.test: registered 0 subscriptions and 1 schedule 17.8.2022, 15:17:02.293 [error]: javascript.0 (1151) script.js.Allgemein.Crypto.Helium.test: ReferenceError: writeValueOverview is not defined 17.8.2022, 15:17:02.293 [error]: javascript.0 (1151) at script.js.Allgemein.Crypto.Helium.test:75:1 17.8.2022, 15:17:02.293 [error]: javascript.0 (1151) at script.js.Allgemein.Crypto.Helium.test:79:3 17.8.2022, 15:17:03.451 [info ]: javascript.0 (1151) script.js.Allgemein.Crypto.Helium.test: {'total':0.3685975,'sum':36859750,'stddev':0.0094209479866946,'min':0,'median':0.01122825,'max':0,'avg':0.012710258620689655} 17.8.2022, 15:17:04.390 [info ]: javascript.0 (1151) script.js.Allgemein.Crypto.Helium.test: {'total':0.06173936,'sum':6173936,'stddev':0.018747958871,'min':0,'median':0.01570541,'max':0,'avg':0.020579786666666666} 17.8.2022, 15:17:05.389 [info ]: javascript.0 (1151) script.js.Allgemein.Crypto.Helium.test: {'total':0.3685975,'sum':36859750,'stddev':0.0094209479866946,'min':0,'median':0.01122825,'max':0,'avg':0.012710258620689655} 17.8.2022, 15:17:06.625 [info ]: javascript.0 (1151) script.js.Allgemein.Crypto.Helium.test: {'total':0.3685975,'sum':36859750,'stddev':0.0094209479866946,'min':0,'median':0.01122825,'max':0,'avg':0.012710258620689655}
Mir ist bewusst, dass writeValueOverview nicht definiert ist, ich weiß nur nicht wie ich das mache. Thema fehlendes Basiswissen zum Thema Javascript. Bisher habe ich meine Skripte immer irgendwie zusammenkopiert nach dem try&error Prinzip.
Da in dem Skript vom Prinzip 4 mal der gleiche Code genutzt wird, verstehe ich nicht, warum der Fehler nur bei einer Funktion vorhanden ist und nicht bei allen vieren. Vor allem, weil das Skript ja erfolgreich die Daten holt. Muss ich am Anfang im Skript einfach eine Definition festlegen? Wenn ja, wie mache ich das?
-
@unbekannt
Jetzt wird es durcheinander. Poste bitte die aktuelle Skriptversion zu der das debig Log passt dazu.
Zu diesem Log kann ich jetzt kein Skriptbeispiel mehr findenDa wo du die Funktionen in settimeout callbacks gepackt hast, sind eigentlich immer anonyme Funktionen. Den Namen den du da vergibst gilt nur innerhalb des settimeout Aufrufs
Daher ist der Name unnötig
Und der Aufruf weiter unten schlägt fehlDas mit settimeout zu machen ist nicht richtig auch wenn es wohl das Problem löst. Irgendwann passt das Zeitverhalten nicht mehr und dann klappt es wieder nicht.
https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Functions
Was funktionierte bei meinem Beispiel konkret nicht?
-
@oliverio
Ich versuche es mal. Also hier dein Skript mit diesen Anpassungen:- Miner ID ergänzt/ausgetauscht
- Zeile 6 &12 dp2 entfernt (benötige ich nicht)
- Zeile 9 (url) zu (v_url) geändert (sonst bekomme ich den Fehler, das url nicht definiert ist)
- Zeile 21 & 29 data.total ergänzt statt Fragezeichen
- Zeile 30 gelöscht
- Zeile 42 zum Testen auf jede Minute geändert
Hier das Skript:
Ich habe das Skript mal laufen gelassen und festgestellt, das Resultat nach jedem Abruf unterschiedlich ist. Mal bekomme ich einen Fehler, mal mehrere und manchmal keine.
Hier die Ausgabe:Fehler Nr.1
Fehler Nr.2
hier mal kein Fehler
Fehler Nr.3
Wie du siehst geht es manchmal gut, manchmal aber auch nicht. Wie würdest du das lösen?
-
@unbekannt
Schau ich mir Anfang der nö hatten Woche im Detail an. Bin Grad ni ht an einem RechnerDer Fehler 429 kann 2 Möglichkeiten haben.
Einmal too many requests. Anbieter versuchen die Häufigkeit der Anfragen in einem bestimmten Zeitabschnitt zu limitieren. Das muss man beachten. Hab aber auf die schnelle keine Regel gefunden
Allerdings hab ich gefunden das man einen User-Agent String mit angeben muss da ansonsten genau mit 429 abgebrochen wird. Evtl findest du dazu Details. Wenn du im Internet suchst dann findest Angaben bspw zu Chrome oder Firefox. Welcher ist relativ egal -
@oliverio
Ja, dass der Fehler wegen zu vieler Anfragen kommt, hatte ich auch recherchiert, daher wollte ich ja den Timeout setzen. Aber du meintest ja, dass es so wie ich es gemacht habe nicht optimal ist.Ich habe jetzt einen anderen Ansatz gewählt und einfach mal ganz pragmatisch den cronjob angepasst, damit läuft das Skript auf jeden Fall fehlerfrei.
Ich danke dir auf jeden Fall für deinen Input, ich habe eine Menge gelernt
Für die, die es interessiert, hier das funktionierende Skript. Ihr müsst nur "dp1" und die Miner-ID anpassen:
-
@unbekannt
das hatte hier ich als andere alternative auch geschrieben
die skript detail sachen kann ich fühestens erst ab montag wieder schauen
-
ich habe den folgenden Code ausprobiert. Das schedule habe ich aus testzwecken entfernt.
Er hat einwandfrei funktioniert.
Gab es jetzt noch ein Problem.
Den Useragent hast ja auch ergänzt.
Hab daher nun kein 429 mehr erhalten. -
@oliverio Hi
ich beschäftige mich auch gerade mit dem auslesen von der API
aber im moment blicke ich garnichts.
Ich habe Iobroker und Grafana am laufen.
Und möchte auch die Daten aus der Helium Api auslesen.
Es hapert aber schon an diesem Axis. Muss man das im Iobroker einrichten oder wie benutze ich dieses Script.
Sorry für diese doofe Frage. -
axios ist eine zusätzliche bibliothek, mit der man http-abfragen machen kann.
also genau die art von abfragen, die der browser im hintergrund macht.axios wird auch von iobroker intern verwendet, aber um sicher zu gehen,
sollte man ihn in den einstellungen des javascript-adapters im feld "zusätzliche npm module" eintragen. also einfach "axios" eintragen.
danach kann im javascript diese bibiothek mitvar axios = require("axios");
verwendet werden.
welche befehle und parameter zur verfügung stehen, kann man in der doku nachlesen
https://axios-http.com/docs/api_intro