Tibber API - Real Time Subscription mit Python

@luchbewohner Hi.

Tjaa, ich hab jetzt alles versucht, was ich kann. Ich bin jetzt noch mal auf den Original-Code zurückgegangen, benenne kurz token und home-id. Wenn das Skript läuft, dann kommt entweder der Too many connections Fehler oder eben nichts. Was aber auch nicht verwunderlich ist, es gibt ja im gesamten Skript keine Ausgabe der Werte. Wo müsste ich also wenigstensein "print" anbringen?

Wenn ich's hier hinsetze:

    try:
for result in ws_client.subscribe(subscription):
print(result)
console_handler(result)

dann kommt dabei heraus:

tibberpulse-influxdb
Sleep for 5 secs.
Run GQL query.
{'liveMeasurement': {'timestamp': '2023-12-21T14:24:34.000+01:00', 'power': 2210.4, 'accumulatedConsumption': 4.1975, 'accumulatedCost':
0.939531, 'voltagePhase1': None, 'voltagePhase2': None, 'voltagePhase3': None, 'currentL1': None, 'currentL2': None, 'currentL3':
None, 'lastMeterConsumption': 3742.3657}}
Exception ignored in: <async_generator object Client.subscribe_async at 0x754d0a30>
RuntimeError: async generator ignored GeneratorExit

Mehr will ich ja eigentlich gar nicht. Power ist ja da. Aber danach ist eben minutenlang Ebbe. Was die Fehlermeldungen angeht: keine Ahnung. Damit kann ich jetzt auch nichts anfangen. Aber vielleicht liegt der Hase ja genau dort im Pfeffer(?)

Ich rufe übrigens das pulse.py direkt von der Konsole aus auf. Das sollte wohl ok sein. Oder ist das der Fehler?

Hättest Du Lust, mir mal Dein Skipt zu geben? Irgendwo ist bei mir ja Wurm drin und ich komm' nicht drauf, was genau ich mit dem console_handler abrufen muss und wo besser keine Schleife laufen sollte... :thinking:

PS: Die Connections scheinen sich übrigens so halbwegs zurücksetzen zu lassen, wenn man die RealTimeSubscription im API Explorer nutzt. Da kommt dann auch erst noch dieselbe Fehlermeldung. Anschließend funktioniert es dann, und dann (manchmal) auch wieder mit dem Pythonscript.

@zx6r Vielen lieben Dank für die schnelle Antwort! Kann es sein, dass der Installationfolder "sol" im Projekt solpiplog" fehlt?

habe es gefunden :slight_smile: Releases · njfaria/SolPipLog · GitHub

@monokristallin

Hab das ganze in Github abgelegt.
Viel Spass damit.

@solarffm Möglich ist das .. Ich hatte zunächst eine älter Version laufen und bin erst später auf 3.11 umgestiegen.

Am ende sollte es so aussehen! Glaube man musste auch die Benutzerrechte damals anpassen.

Es gibt aber auch Fertige Images für den Pi. Da ist dann gleich Emoncms mit drauf! Musst mal im www.photovoltaikforum.com suchen.. da hatte ich es auch bekommen :slight_smile:

https://www.photovoltaikforum.com/core/attachment/175407-handbuch-emoncms-pdf/

Das sieht dann am ende z.b. so aus :slight_smile:

@solarffm Und? Hat es funktioniert :slight_smile:

Hey,

vielen Dank! Damit spiele ich mal herum, sobald der Weihnachtstrubel vorüber ist. Da stecke ich schon mittendrin. :wink:

Ich werde mal berichten.

Allerdings läuft auf meinem Pi auch Python 3.7. Mir 3.9.x läufen einige andere Routinen wieder nicht, deshalb kann ich da nicht upgraden. Ich werd's mal testen...

Hi mdkell.

Okay, ich habe mal alles installiert was man dazu wohl braucht und mir dieses, für Node-Red Anfänger wirklich sehr lehrreiche, Video angeschaut:

Das hier beschriebene ist tatsächlich leicht nachzuvollziehen und ich kann, zumindest im debug-Fenster so ziemlich alle Daten sehen.

Wie das mit den Live-Daten geht, lässt sich hieraus ableiten:

Hier hat sich jemand das Node-Red in den IOBroker heineingeladen und sich dann die Tibber Nodes nachinstalliert. Funktioniert dann aber genauso. Mit einer kleinen Funktion

var newmsg = {payload: msg.payload.power};
return newmsg;

(function-node) schiebt er mir nun ständig den aktuellen Tibber Pulse power-Wert ins debug-Fenster.

Das einzige das mir nun noch fehlt ist: wie lese ich den Wert von außen wieder aus? Ich ziehe mir die Batterie- und Solarcharger Werte mit python über Modbus-TCP vom Venus in meinen Pi, der eigentlich die Hauptaufgaben erledigt. Das macht man über die ID und die auslebaren Register, die dahinter stehen.

Das scheint hier aber nicht der richtige Weg zu sein. Weiß also jemand, wie ich "von außen" einen Wert, der im Debug-Fesnter bereits ständig korrekt aktualisiert wird, ganz simpel mit einem anderen Pi, bestenfalls über Python, auslesen kann? Vielleicht über http? Dummerweise stehe ich bei dieser Aufgabe bei Node-Red, die doch nun wirklich die allereinfachste von allen sein sollte, wieder mal wie der Ochs vor'm Berg. :expressionless:

Vielen Dank vorab...

Läuft auf deinem pi z.b. ein MQTT Broker?.. dann schicke es einfach via MQTT.. es gibt dafür einen fertigen Node..

@mdkeil

Hi mdkeil. Auch ein schöner Ansatz, vor allem in Sachen Usability.

Bei mir läuft es, seit ein paar Tagen via Python Script an den besagten Raspi-MQTT-Server.

Frage: Hast du Langzeiterfahrungen mit Tibber in Kombination mit dem Node?

Ich frage deshalb, weil ich gesehen habe, dass die Verbindung zu Tibber bei mir zuweilen abbricht (connection closed) und dann beim Reconnecten das hier kommt/kommen kann:

Too many open connections on this server: 2;

In dem Fall muss(?) man sich einen neuen API Key holen; Warten hat nicht geholfen. Das API Key holen kann ich zwar auch automatisieren, bedeutet aber zusätzlichen und hoffentlich vermeidbaren Aufwand.

Du meinst, auf dem auslesenden Pi? Nein. Eigentlich wollte ich den auch so schlank wie möglich belassen. Was mich ärgert, ist dass das hier:

irgendiw nicht funktioniert. Damit soll mal, so wie ich das lese, bereits vorhandenen Geräten unter ser entsprechenden ID und dem entsprechenden Register, wie z.B.

ID 100 (Venus System) und den Register 820 (/Ac/Grid/L1/Power) beschreiben können. Allerdings steht in der List auch explizit, dass dieser Werte eben nicht writeable ist. Das gilt aber für so ziemlich alle Werte. Wenn ich ihn aus lese, dann bekomme ich immer "0" als Antwort.

So habe ich's gemacht (siehe untere Kette):

Irgendetwas verstehe ich da offensichtlich falsch.

Hi, da kann ich mal eben reingrätschen. Vielen Dank noch für Deinen Ansatz. Den habe ich gestern auch noch einmal ausprobiert und es läuft immerhin. Aber wie Du sagst, eben nicht wirklich stabil. Es kommt hin und wieder immer noch zu dem "Too many connections" Fehler.

Der Node-Red Node läuft bei mir absolut stabil. Ich hatte ihn gestern gestartet, und er hat heute morgen immernoch fein seine Daten ans Debug-Fenster gesendet. Siehe Bild im Post über diesem. Leider komme ich an die Daten jetzt nicht heran. Für einen erfahrenen Node.Red Spezialisten wohl kein Problem. Als Node-Red-Anfänger kann ich bis jetzt leider nur mit den Schultern zucken.

Und den MQTT Broker wollte ich erst mal nicht installieren. Da sollte es einen einfacheren Weg geben. Aber wenn nicht, dann werde ich darum wohl uch nicht herumkommen. Dann ist mein System aber wirklich nicht mehr "keep it simple".

1 „Gefällt mir“

@monokristallin Tatsächlich läuft meiner Konstrukt seit 36h auch stabil. Aber ich möchte natürlich nicht von einer Tagesform (egal ob Tibber-Api, Python oder 3rd Party libs) abhängig sein. Von daher sind deine langfristigen Beobachtungen für mich sehr interessant. :+1:

Ja, Dein Skipt läuft soweit. Allerdings läuft da ja etwas im Hintergrund. Den Main-Part würde ich ja jedes Mal mit starten, wenn mein Hauptskript läuft. So wie ich das sehe, laufen dann zwei Instanzen, die dann zu viel für Tibber sind. Zumindest erkläre ich mir das so. Bei Node-Red kann ich so oft neustarten wie ich will, das funktioniert.

Wenn ich jetzt nur noch die Zahlen, die ich da durchrauschen sehe, auch vom anderen Pi auslesen könnte. Es gibt da ja Netzwerk-Nodes. Aber die habe ich allesamt nicht wirklich verstanden, bzw. diese sind wohl irgendwie für andere Dinge gebaut worden, als einzelene Werte zur Verfügung zu stellen. Aber wie gesagt, ich habe gestern erst angefangen, mit Node-Red. Vielleicht komme ich ja noch selbst drauf. Aber jede Hilfe ist sehr willkommen...

@luchbewohner

Ich selbst nutze die Tibber Nodes nur zum Auslesen der Preise, da ich einen separaten IR Lesekopf verwende und die Daten direkt auslese und die Daten manuell an Tibber sendet.. funktioniert seit über 2 Monaten tadellos.

@Monokristallin

Ich mache mir heute Abend mal Gedanken, wie Du die Daten sonst noch auf deinen externen Pi bekommst.

quick and dirty http-endpoint :wink:

node_red_flow.jpg

http_response.jpg

Der Wert selbst liegt in einer globalen Variablen (global.get("fronius.meter")).. zu setzen z.B. mit global.set("variable",wert);

[
{
"id": "edeb5b596a7cec77",
"type": "http in",
"z": "03ddae67b0473922",
"name": "",
"url": "/api",
"method": "get",
"upload": false,
"swaggerDoc": "",
"x": 160,
"y": 120,
"wires": [
[
"7bf4ca40c5400086"
]
]
},
{
"id": "7bf4ca40c5400086",
"type": "function",
"z": "03ddae67b0473922",
"name": "json",
"func": "msg.payload = {gridpower: global.get('fronius.meter')};\nmsg.headers = {};\nmsg.headers['content-type'] = 'application/json';\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 330,
"y": 120,
"wires": [
[
"7883d17ca80f0090"
]
]
},
{
"id": "7883d17ca80f0090",
"type": "http response",
"z": "03ddae67b0473922",
"name": "http Response",
"statusCode": "",
"headers": {},
"x": 560,
"y": 120,
"wires": []
}
]

..zusätzlich noch in eine globale Variable geschrieben, die du dann für den http-Endpunkt verwenden kannst.

var newmsg = {payload: msg.payload.power};
global.set("tibber.power",newmsg);
return newmsg;

Hi @mdkeil

Ja, vielen Dank!! Das sieht ja schon mal ganz gut aus. Leider kann ich es gerade nicht wirklich testen, da Tibber wohl gerade ein Serverproblem hat. Weder kann sich der Node verbinden, noch bringt der APi Explorer bei Tibber selbst Werte ("Your subscription data will appear here after server publication")

Vielleicht gibt sich das ja noch im Laufe des Tages.

Allerdings, so fürchte ich, musst Du mich, was das Füllen der Nodes angeht, noch ein paar Meter weiter vorne abholen. Ich habe das mit dem HTTP Request noch nicht ganz verstanden. Macht es Sinn, wenn ich die Felder so fülle?

Inbesondere bei der Function sollte das ja so nicht gehen. Ein json-Format ist ja keine Funktion. Das werde ich sicherlich so falsch gemacht haben. Aber auch die http-Nodes werde ich wohl falsch ausgefüllt haben.

Aber immerhin habe ich das mit der globalen Variable und dem anschließenden Auslesen verstanden. :wink:

Vielen Dank nochmals bisher und auch vorab...

Ich ich viel schreibe.. das was ich oben im Code-block gepostet habe sind die entsprechenden Node als json exportiert.. das kannst Du Copy+Paste so in Node Red importieren.. dann brauchst Du in dem Funktion-Node nur noch die globale Variable anpassen.

Tjaa,

leider hat wohl unser (erwiesermaßen leider ganz außergewöhlich dämlicher) Hausmeister meinen Pulse abgezogen und im Keller versteckt. Darauf musste erst mal kommen. :disappointed:

Jetzt läuft alles wieder.

Okay, das mit dem Import war mir neu. Sehr praktisch! :+1:

Wie das mit den http request funktionieren sollte kann man prima in diesem kurzen Video sehen:

Leider, leider, leider komme ich nur bis 0:55, wo man eigentlich {} im Browser sehen sollte.

Gebe ich im Broser

venus.local

ein, dann sehe ich die Konsole. Gebe ich jetzt

venus.local:1880/test (oder venus.local:1880/api) ein, dann steht im Browser:

Fehler: Verbindung fehlgeschlagen Firefox kann keine Verbindung zu dem Server unter venus.local:1880 aufbauen.
Desselbe, wenn ich die Venus-IP angebe. Woran kann das denn nun schon wieder liegen? 😧 Muss man generell noch einen Service im Node Red aktivieren?

Hättest Du sonst mal Lust, die beiden http Nodes auch zu exportieren?

Irgendwie steckt da bei mir immer noch der Wurm drin.

PS: Mir scheint das ein Bug im neuen Raspberry VenusOS zu sein. Ich habe Version 3.13 Large. Vielleicht hat das Problem ja mit dieser Version sont noch jemand. Ich habe die Frage jetzt mal im Victron Forum gepostet. Mal schauen, ob da jemand Rat weiß...

PPS: Ein Update auf Version 3.20~45 (und Node-Red 3.1) hat jedenfalls noch keine Besserung gebracht.

glaube ich nicht.. läuft bei mir mit der 3.20 ~35 problemlos

ups.. dachte oben wäre alles komplett.. war ja nur der function-node..

hier einmal komplett.. werde ich oben dann auch ändern :slight_smile: /p>

[
{
"id": "edeb5b596a7cec77",
"type": "http in",
"z": "03ddae67b0473922",
"name": "",
"url": "/api",
"method": "get",
"upload": false,
"swaggerDoc": "",
"x": 160,
"y": 120,
"wires": [
[
"7bf4ca40c5400086"
]
]
},
{
"id": "7bf4ca40c5400086",
"type": "function",
"z": "03ddae67b0473922",
"name": "json",
"func": "msg.payload = {gridpower: global.get('fronius.meter')};\nmsg.headers = {};\nmsg.headers['content-type'] = 'application/json';\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 330,
"y": 120,
"wires": [
[
"7883d17ca80f0090"
]
]
},
{
"id": "7883d17ca80f0090",
"type": "http response",
"z": "03ddae67b0473922",
"name": "http Response",
"statusCode": "",
"headers": {},
"x": 560,
"y": 120,
"wires": []
}
]