 Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
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
"AC": {
"0": {
"Power": {
"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?
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:
???
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.600
0061,"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},"Yield
Total":{"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},"Voltag
e":{"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}}},"e
vents":3},{"serial":"114190138728","name":"WR-2","order":1,"data_age":2,
"poll_enabled":true,"reachable":true,"producing":true,"limit_relative":1
00,"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},"YieldTo
tal":{"v":260.0679932,"u":"kWh","d":3},"Frequency":{"v":49.97999954,"u":
"Hz","d":2},"PowerFactor":{"v":1,"u":"","d":3},"ReactivePower":{"v":0.30
0000012,"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.64
900208,"u":"kWh","d":3},"Irradiation":{"v":58.20000076,"u":"%","d":3,"ma
x":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.4
190063,"u":"kWh","d":3},"Irradiation":{"v":55.73626709,"u":"%","d":3,"ma
x":455}}},"INV":{"0":{"Temperature":{"v":43.29999924,"u":"\xc2\xb0C","d"
:1}}},"events":1}],"total":{"Power":{"v":805.8000488,"u":"W","d":1},"Yie
ldDay":{"v":1630,"u":"Wh","d":0},"YieldTotal":{"v":618.8609619,"u":"kWh"
,"d":3}},"hints":{"time_sync":false,"radio_problem":false,"default_passw
ord":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).
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|