Haus & Smart Home
›
Thread
OpenDTU WEB-api
Hallo,
ich habe zwei HM800 Wechselrichter an einer OpenDTU. Von meinem Laptop kann ich mit
curl --no-progress-meter http://192.168.0.153/api/livedata/status | jq
alle möglichen Livedaten in Form einer langen Liste auslesen, die so aussieht:
{
"inverters": [
{
"serial": "114190651346",
"name": "WR-1",
"order": 0,
"data_age": 0,
"poll_enabled": true,
"reachable": true,
"producing": true,
"limit_relative": 100,
"limit_absolute": 800,
"AC": {
"0": {
"Power": {
"v": 323.7999878,
"u": "W",
"d": 1
},
"Voltage": {
"v": 227.6999969,
"u": "V",
"d": 1
},
.
.
.
],
"total": {
"Power": {
"v": 542.2999878,
"u": "W",
"d": 1
},
"YieldDay": {
"v": 721,
"u": "Wh",
"d": 0
},
"YieldTotal": {
"v": 611.6069946,
"u": "kWh",
"d": 3
}
},
"hints": {
"time_sync": false,
"radio_problem": false,
"default_password": false
}
}
Mit
curl --no-progress-meter http://192.168.0.153/api/livedata/status | jq '.total | .Power.v'
erhalte ich die momentan gelieferte Leistung beider WR zusammen.
Ich hätte aber gerne die Leistungen beider Wechselrichter getrennt.
Mit
curl --no-progress-meter http://192.168.0.153/api/livedata/status?inv=114190651346 | jq
bekomme ich genau die selbe lange Liste. Die Doku zur WEB-api habe ich zwar gelesen, verstehe aber trotzdem nicht, wie ich an den Wert
1
"AC": {
2
"0": {
3
"Power": {
4
"v": 323.7999878
des Wechselrichters 114190651346 komme. Ich möchte die momentane Leistung (also hier 323.7999878) in eine Variable schreiben. Kann mir da bitte jemand weiterhelfen?
Oh, ich sehe gerade in der Vorschau, dass die Formatierung der Liste verloren gegangen ist. Ich weiß auch nicht, wie ich das verhindern kann.
Das Manual zu jd ist dein Freund.
https://jqlang.github.io/jq/manual
Und auf https://jqplay.org/ kannst du es dann direkt ausprobieren.
Mit .inverters[0].AC."0".Power.v kommst Du an den Wert des ersten Inverters.
Ich nutze für sowas meinen MQTT Broker (mosquitto). Da kann ich dann direkt auf die Werte zugreifen (ohne erst die JSON Antwort parsen zu müssen).
@mha1
Vielen Dank für Deine schnelle Antwort.
Das ist auch genau die Lösung, die ich gesucht habe. Das Doku-lesen ist ja, ach, so anstrengend. Es ist ja viel einfacher, stundenlang herum zu probieren, als fünf Minuten in die Doku zu schaun, oder?
Na ja, ich hätte mir ja eigentlich denken können, dass ich mich zu früh gefreut habe. Das mit "curl" funktioniert wunderbar auf der Befehlszeile, ich erhalte den richtigen Wert.
Aber diesen Wert möchte ich ja in einem Python-Script einer Variablen zuweisen, und Python kann mit "curl" wohl nichts anfangen.
Nach etwas Stöbern bin ich auf die requests-library gestoßen, und habe folgendes probiert:
1
#! /usr/bin/env python3
2
3
import requests
4
5
r = requests . get ( f " http://192.168.0.153/api/livedata/status " )
6
7
print ( r . content )
Hiermit erhalte ich diese lange Liste, die aber auch enthält, was ich suche:
1
b'{"inverters":[{"serial":"114190651346","name":"WR-1","order":0,"data_age":1,"poll_enabled":true,"reachable":true,"producing":true,"limit_relative":100,"limit_absolute":800,"AC":{"0":{"Power":{"v":453.6000061,"u":"W","d":1},"Voltage":{"v":229.3999939,"u":"V","d":1},"Current":{"v":1.980000019,"u":"A","d":2},"Power DC":{"v":476.5,"u":"W","d":1},"YieldDay":{"v":990,"u":"Wh","d":0},"YieldTotal":{"v":358.7929993,"u":"kWh","d":3},"Frequency":{"v":49.97999954,"u":"Hz","d":2},"PowerFactor":{"v":1,"u":"","d":3},"ReactivePower":{"v":0,"u":"var","d":1},"Efficiency":{"v":95.19412231,"u":"%","d":3}}},"DC":{"0":{"name":{"u":"West"},"Power":{"v":221.1000061,"u":"W","d":1},"Voltage":{"v":25.70000076,"u":"V","d":1},"Current":{"v":8.609999657,"u":"A","d":2},"YieldDay":{"v":473,"u":"Wh","d":0},"YieldTotal":{"v":170.3939972,"u":"kWh","d":3},"Irradiation":{"v":48.59340668,"u":"%","d":3,"max":455}},"1":{"name":{"u":"Mitte"},"Power":{"v":255.3999939,"u":"W","d":1},"Voltage":{"v":27.79999924,"u":"V","d":1},"Current":{"v":9.180000305,"u":"A","d":2},"YieldDay":{"v":517,"u":"Wh","d":0},"YieldTotal":{"v":188.3990021,"u":"kWh","d":3},"Irradiation":{"v":56.13187027,"u":"%","d":3,"max":455}}},"INV":{"0":{"Temperature":{"v":48.90000153,"u":"\xc2\xb0C","d":1}}},"events":3},{"serial":"114190138728","name":"WR-2","order":1,"data_age":2,"poll_enabled":true,"reachable":true,"producing":true,"limit_relative":100,"limit_absolute":800,"AC":{"0":{"Power":{"v":352.2000122,"u":"W","d":1},"Voltage":{"v":230.3999939,"u":"V","d":1},"Current":{"v":1.529999971,"u":"A","d":2},"Power DC":{"v":370,"u":"W","d":1},"YieldDay":{"v":640,"u":"Wh","d":0},"YieldTotal":{"v":260.0679932,"u":"kWh","d":3},"Frequency":{"v":49.97999954,"u":"Hz","d":2},"PowerFactor":{"v":1,"u":"","d":3},"ReactivePower":{"v":0.300000012,"u":"var","d":1},"Efficiency":{"v":95.18919373,"u":"%","d":3}}},"DC":{"0":{"name":{"u":"Balkon"},"Power":{"v":116.4000015,"u":"W","d":1},"Voltage":{"v":31.79999924,"u":"V","d":1},"Current":{"v":3.660000086,"u":"A","d":2},"YieldDay":{"v":128,"u":"Wh","d":0},"YieldTotal":{"v":67.64900208,"u":"kWh","d":3},"Irradiation":{"v":58.20000076,"u":"%","d":3,"max":200}},"1":{"name":{"u":"Ost"},"Power":{"v":253.6000061,"u":"W","d":1},"Voltage":{"v":27.70000076,"u":"V","d":1},"Current":{"v":9.170000076,"u":"A","d":2},"YieldDay":{"v":512,"u":"Wh","d":0},"YieldTotal":{"v":192.4190063,"u":"kWh","d":3},"Irradiation":{"v":55.73626709,"u":"%","d":3,"max":455}}},"INV":{"0":{"Temperature":{"v":43.29999924,"u":"\xc2\xb0C","d":1}}},"events":1}],"total":{"Power":{"v":805.8000488,"u":"W","d":1},"YieldDay":{"v":1630,"u":"Wh","d":0},"YieldTotal":{"v":618.8609619,"u":"kWh","d":3}},"hints":{"time_sync":false,"radio_problem":false,"default_password":true}}'
Sieht ja schon mal gut aus. ich brauche aus der Zeile
"AC":{"0":{"Power":{"v":453.6000061,"u":"W","d":1}
also diesen Wert 453.6.
Dann habe ich (analog zur curl-Zeile) folgendes versucht:
1
r = requests.get(f"http://192.168.0.153/api/livedata/status").json()['.inverters[0].AC."0".Power.v']
bekomme aber damit den Fehler:
1
KeyError: '.inverters[0].AC."0".Power.v'
Natürlich habe ich in die requests Doku geschaut, aber auch hier wird ein Grundwissen vorausgesetzt, das ich einfach nicht habe. Ich kann {},[],(),:,' nicht richtig interpretieren. Ich sehe zwar, dass ein Fehler aufgetreten ist, aber ich weiß nicht, wie ich ihn vermeiden kann. Vermutlich ist das ganz einfach, man muss nur wissen, wie.
Wie lautet die alte Weisheit?:
1
Wissen ist Macht!
2
Weißt' nix?
3
Macht nix!
4
Frag halt!
Das mache ich dann hiermit.
Kann mir jemand den richtigen Tip geben?
UL
Uwe L.
(ul5255)
09.07.2024 12:15
#7699142
vllt. so?
r = requests.get(f"...").json()['inverters'][0]['AC']['0']['Power']['v']
@Uwe L.
Nö,
1
TypeError: list indices must be integers or slices, not str
Lasse ich bei der ersten 0 die Hochkommata weg:
1
AttributeError: 'float' object has no attribute 'status_code'
Also mache ich die Hochkommas da wieder hin und entferne sie bei der zweiten 0.
1
TypeError: list indices must be integers or slices, not str
Mache ich sie bei beiden weg:
???
UL
Uwe L.
(ul5255)
09.07.2024 14:27
#7699219
gerade online (https://www.online-python.com/kM5vqwXzlA ) ausprobiert:
import json
x = json.loads(b'{"inverters":[{"serial":"114190651346","name":"WR-1","order":0,"data_age":1,"poll_enabled":true,"reachable":true,"producing":true,"limit_relative":100,"limit_absolute":800,"AC":{"0":{"Power":{"v":453.6000061,"u":"W","d":1},"Voltage":{"v":229.3999939,"u":"V","d":1},"Current":{"v":1.980000019,"u":"A","d":2},"Power DC":{"v":476.5,"u":"W","d":1},"YieldDay":{"v":990,"u":"Wh","d":0},"YieldTotal":{"v":358.7929993,"u":"kWh","d":3},"Frequency":{"v":49.97999954,"u":"Hz","d":2},"PowerFactor":{"v":1,"u":"","d":3},"ReactivePower":{"v":0,"u":"var","d":1},"Efficiency":{"v":95.19412231,"u":"%","d":3}}},"DC":{"0":{"name":{"u":"West"},"Power":{"v":221.1000061,"u":"W","d":1},"Voltage":{"v":25.70000076,"u":"V","d":1},"Current":{"v":8.609999657,"u":"A","d":2},"YieldDay":{"v":473,"u":"Wh","d":0},"YieldTotal":{"v":170.3939972,"u":"kWh","d":3},"Irradiation":{"v":48.59340668,"u":"%","d":3,"max":455}},"1":{"name":{"u":"Mitte"},"Power":{"v":255.3999939,"u":"W","d":1},"Voltage":{"v":27.79999924,"u":"V","d":1},"Current":{"v":9.180000305,"u":"A","d":2},"YieldDay":{"v":517,"u":"Wh","d":0},"YieldTotal":{"v":188.3990021,"u":"kWh","d":3},"Irradiation":{"v":56.13187027,"u":"%","d":3,"max":455}}},"INV":{"0":{"Temperature":{"v":48.90000153,"u":"\xc2\xb0C","d":1}}},"events":3},{"serial":"114190138728","name":"WR-2","order":1,"data_age":2,"poll_enabled":true,"reachable":true,"producing":true,"limit_relative":100,"limit_absolute":800,"AC":{"0":{"Power":{"v":352.2000122,"u":"W","d":1},"Voltage":{"v":230.3999939,"u":"V","d":1},"Current":{"v":1.529999971,"u":"A","d":2},"Power DC":{"v":370,"u":"W","d":1},"YieldDay":{"v":640,"u":"Wh","d":0},"YieldTotal":{"v":260.0679932,"u":"kWh","d":3},"Frequency":{"v":49.97999954,"u":"Hz","d":2},"PowerFactor":{"v":1,"u":"","d":3},"ReactivePower":{"v":0.300000012,"u":"var","d":1},"Efficiency":{"v":95.18919373,"u":"%","d":3}}},"DC":{"0":{"name":{"u":"Balkon"},"Power":{"v":116.4000015,"u":"W","d":1},"Voltage":{"v":31.79999924,"u":"V","d":1},"Current":{"v":3.660000086,"u":"A","d":2},"YieldDay":{"v":128,"u":"Wh","d":0},"YieldTotal":{"v":67.64900208,"u":"kWh","d":3},"Irradiation":{"v":58.20000076,"u":"%","d":3,"max":200}},"1":{"name":{"u":"Ost"},"Power":{"v":253.6000061,"u":"W","d":1},"Voltage":{"v":27.70000076,"u":"V","d":1},"Current":{"v":9.170000076,"u":"A","d":2},"YieldDay":{"v":512,"u":"Wh","d":0},"YieldTotal":{"v":192.4190063,"u":"kWh","d":3},"Irradiation":{"v":55.73626709,"u":"%","d":3,"max":455}}},"INV":{"0":{"Temperature":{"v":43.29999924,"u":"\xc2\xb0C","d":1}}},"events":1}],"total":{"Power":{"v":805.8000488,"u":"W","d":1},"YieldDay":{"v":1630,"u":"Wh","d":0},"YieldTotal":{"v":618.8609619,"u":"kWh","d":3}},"hints":{"time_sync":false,"radio_problem":false,"default_password":true}}')
print(x['inverters'][0]['AC']['0']['Power']['v'])
gibt aus: 453.60000 ....
@Uwe L.
Ja, das war's, das geht bei mir jetzt auch. Der Knackpunkt war wohl das fehlende "import json" und die "json.loads" Anweisung.
Merkwürdig finde ich allerdings, dass ich im gleichen Script schon auf zwei unterschiedliche shellys zugreife (ein- und dreiphasiger Leistungsmesser).
Auch hier benutze ich die requests-library und json, und das funktioniert, ohne dass ich explizit json importieren musste.
Nur zur Info:
den einphasigen shelly lese ich so aus:
1
sh_1=requests.get(f'http://ipaddr/rpc/PM1.GetStatus?id=0').json()["apower"]
und den dreiphasigen so:
1
sh_3=requests.get(f'http://ipaddr/rpc/EM.GetStatus?id=0').json()["total_act_power"]
Die entsprechenden Zeilen habe ich irgendwo im Netz gefunden, alleine wäre ich da nie drauf gekommen. Diese Zeilen habe ich mir zum Vorbild genommen, um auch auf den Wechselrichter (über OpenDTU) zuzugreifen. Aber das war wohl nichts.
Dir ganz herzlichen Dank, jetzt kann ich endlich weiterbasteln, das nächste Problem wartet schon auf mich (und die mikrocontroller-Gemeinde).
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.
Noch kein Account?
Die Registrierung ist kostenlos und dauert nur eine Minute.
Jetzt registrieren