Mal wieder: JSON Abfrage mit HTTPMOD

Begonnen von FHEMAN, 12 Mai 2023, 17:14:20

Vorheriges Thema - Nächstes Thema

FHEMAN

Hallo,

ich möchte die lokale Website unseres SMA Wechselrichters auslesen via HTTPMOD.

Da ich nicht der erste bin mit dieser Idee, wollte ich diese Vorlage nutzen:
https://github.com/littleyoda/Home-Assistant-Tripower-X-MQTT

Das Python Script macht Folgendes nach meinem Verständnis:
1. Login durch POST auf http://mywr/api/v1/token mit DATA {"grant_type":"password","username":"myuser","password":"mypassword"}
2. Im Erfolgsfall wird der Access Token ausgelesen und der Header weiter aufgebaut via { "Authorization" : "Bearer " + token }
3. Dann ein GET auf die Seite mit den Messwerten http://mywr/api/v1/plants/Plant:1/devices/IGULD:SELF

Ich habe das folgendermaßen versucht, nachzubauen:
list Device
defmod SMAWR HTTPMOD http://mywr/api/v1/plants/Plant:1/devices/IGULD:SELF 60000
attr SMAWR disable 0
attr SMAWR enableControlSet 1
attr SMAWR enableCookies 1
attr SMAWR extractAllJSON 1
attr SMAWR reAuthAlways 1
attr SMAWR reAuthRegex ERROR|Error
attr SMAWR reading1Name SPOT_PDC1
attr SMAWR requestData {"componentId" : "IGULD:SELF"}
attr SMAWR requestHeader1 Accept: application/json
attr SMAWR requestHeader10 Authorization: Bearer $sid
attr SMAWR requestHeader4 Connection: keep-alive
attr SMAWR requestHeader8 Host: mywr
attr SMAWR showBody 1
attr SMAWR showError 1
attr SMAWR showMatched 1
attr SMAWR sid01Data {"grant_type":"password","username":"myuser","password":"mypassword"}
attr SMAWR sid01Header Accept: application/json, text/plain, */
attr SMAWR sid01IdJSON access_token
attr SMAWR sid01URL http://mywr/api/v1/token
attr SMAWR timeout 10

Egal, wie ich es anstelle, ich bekomme nur Error 400: Bad Requests:

Log:
2023.05.12 17:04:14.134 5: SMAWR: set called with reread
2023.05.12 17:04:14.134 4: SMAWR: GetUpdate called (reread)
2023.05.12 17:04:14.134 4: SMAWR: DoAuth called with Steps: 01
2023.05.12 17:04:14.134 5: SMAWR: AddToQueue prepends type auth01 to URL http://mywr/api/v1/token, data {"grant_type":"password","username":"myuser","password":"mypassword"}, header Accept: application/json, text/plain, */, retry 0, initial queue len: 0
2023.05.12 17:04:14.134 5: SMAWR: HandleSendQueue called from DoAuth, qlen = 1
2023.05.12 17:04:14.134 4: SMAWR: HandleSendQueue sends auth01 with timeout 10 to http://mywr/api/v1/token,
data: {"grant_type":"password","username":"myuser","password":"mypassword"},
header: Accept: application/json, text/plain, */
2023.05.12 17:04:14.135 5: SMAWR: AddToQueue adds type update to URL http://mywr/api/v1/plants/Plant:1/devices/IGULD:SELF, data {"componentId" : "IGULD:SELF"}, header Accept: application/json
Authorization: Bearer $sid
Connection: keep-alive
Host: mywr, retry 0, initial queue len: 0
2023.05.12 17:04:14.135 5: SMAWR: HandleSendQueue called from AddToSendQueue, qlen = 1
2023.05.12 17:04:14.135 5: SMAWR: StartQueueTimer called from ReadyForSending sets internal timer to process queue in 1.000 seconds, still waiting for reply to last request
2023-05-12 17:04:14.141 HTTPMOD SMAWR reread
2023.05.12 17:04:14.211 5: SMAWR: ReadCallback called from __ANON__
2023.05.12 17:04:14.211 4: SMAWR: Read callback: request type was auth01 retry 0,
header: HTTP/1.1 400 Bad Request
Date: Fri, 12 May 2023 15:04:14 GMT
Cache-Control: no-cache,no-store,must-revalidate
Pragma: no-cache
Cache-Control: no-store, no body
2023.05.12 17:04:14.211 5: SMAWR: Read callback: body empty
2023.05.12 17:04:14.211 4: SMAWR: BodyDecode is not decoding the response body (charset not found, bodyDecode defaults to none)
2023.05.12 17:04:14.212 5: SMAWR: GetCookies is looking for Cookies
2023.05.12 17:04:14.212 5: SMAWR: ExtractSid called, context sid, num 01
2023.05.12 17:04:14.212 5: SMAWR: Checking SID with JSON access_token
2023.05.12 17:04:14.212 4: SMAWR: checking for redirects, code=400, ignore=0
2023.05.12 17:04:14.212 4: SMAWR: no redirects to handle
2023.05.12 17:04:14.212 5: SMAWR: Read callback sets LAST_REQUEST to auth01
2023-05-12 17:04:14.219 HTTPMOD SMAWR LAST_REQUEST: auth01
2023.05.12 17:04:15.136 5: SMAWR: HandleSendQueue called from Fhem internal timer, qlen = 1
2023.05.12 17:04:15.137 4: SMAWR: HandleSendQueue sends update with timeout 10 to http://mywr/api/v1/plants/Plant:1/devices/IGULD:SELF,
data: {"componentId" : "IGULD:SELF"},
header: Accept: application/json
Authorization: Bearer $sid
Connection: keep-alive
Host: mywr
2023.05.12 17:04:15.170 5: SMAWR: ReadCallback called from __ANON__
2023.05.12 17:04:15.170 5: SMAWR: Read callback Error LogLvl set to 3, regex
2023.05.12 17:04:15.170 3: SMAWR: Read callback: Error: DNS: Cant find host
2023.05.12 17:04:15.170 4: SMAWR: Read callback: request type was update retry 0, no headers, no body
2023.05.12 17:04:15.170 5: SMAWR: Read callback: body empty
2023.05.12 17:04:15.170 4: SMAWR: BodyDecode is not decoding the response body (charset not found, bodyDecode defaults to none)
2023.05.12 17:04:15.171 5: SMAWR: GetCookies is looking for Cookies
2023.05.12 17:04:15.171 5: SMAWR: ExtractSid called, context reading, num unknown
2023.05.12 17:04:15.171 4: SMAWR: no header to look for redirects
2023.05.12 17:04:15.171 5: SMAWR: Read callback sets LAST_REQUEST to update
2023.05.12 17:04:15.171 5: SMAWR: CheckAuth is checking buffer with ReAuthRegex (?^:ERROR|Error)
2023.05.12 17:04:15.171 5: SMAWR: CheckAuth decided no authentication required
2023-05-12 17:04:15.358 HTTPMOD SMAWR LAST_ERROR: DNS: Cant find host
2023-05-12 17:04:15.358 HTTPMOD SMAWR LAST_REQUEST: update
2023.05.12 17:04:37.717 3: SMAWR: Defined with URL http://mywr/api/v1/plants/Plant:1/devices/IGULD:SELF and interval 60000 featurelevel 6.2
2023.05.12 17:04:37.717 4: SMAWR: UpdateTimer called from DefineFn with cmd start sets timer to call update function in 59976.4 sec at 09:44:14.134, interval 60000
2023.05.12 17:04:37.893 5: SMAWR: UpdateHintList called
2023.05.12 17:04:37.893 5: SMAWR: UpdateHintList: setlist = interval reread:noArg stop:noArg start:noArg clearCookies:noArg upgradeAttributes:noArg storeKeyValue
2023.05.12 17:04:37.893 5: SMAWR: UpdateHintList: getlist =
2023-05-12 17:04:37.894 Global global MODIFIED SMAWR
2023.05.12 17:04:41.593 5: SMAWR: set called with reread
2023.05.12 17:04:41.593 4: SMAWR: GetUpdate called (reread)
2023.05.12 17:04:41.593 4: SMAWR: DoAuth called with Steps: 01
2023.05.12 17:04:41.593 5: SMAWR: AddToQueue prepends type auth01 to URL http://mywr/api/v1/token, data {"grant_type":"password","username":"myuser","password":"mypassword"}, header Accept: application/json, text/plain, */, retry 0, initial queue len: 0
2023.05.12 17:04:41.593 5: SMAWR: HandleSendQueue called from DoAuth, qlen = 1
2023.05.12 17:04:41.593 4: SMAWR: HandleSendQueue sends auth01 with timeout 10 to http://mywr/api/v1/token,
data: {"grant_type":"password","username":"myuser","password":"mypassword"},
header: Accept: application/json, text/plain, */
2023.05.12 17:04:41.594 5: SMAWR: AddToQueue adds type update to URL http://mywr/api/v1/plants/Plant:1/devices/IGULD:SELF, data {"componentId" : "IGULD:SELF"}, header Accept: application/json
Authorization: Bearer $sid
Connection: keep-alive
Host: mywr, retry 0, initial queue len: 0
2023.05.12 17:04:41.594 5: SMAWR: HandleSendQueue called from AddToSendQueue, qlen = 1
2023.05.12 17:04:41.594 5: SMAWR: StartQueueTimer called from ReadyForSending sets internal timer to process queue in 1.000 seconds, still waiting for reply to last request
2023-05-12 17:04:41.600 HTTPMOD SMAWR reread
2023.05.12 17:04:41.608 5: SMAWR: ReadCallback called from __ANON__
2023.05.12 17:04:41.608 4: SMAWR: Read callback: request type was auth01 retry 0,
header: HTTP/1.1 400 Bad Request
Date: Fri, 12 May 2023 15:04:41 GMT
Cache-Control: no-cache,no-store,must-revalidate
Pragma: no-cache
Cache-Control: no-store, no body
2023.05.12 17:04:41.608 5: SMAWR: Read callback: body empty
2023.05.12 17:04:41.608 4: SMAWR: BodyDecode is not decoding the response body (charset not found, bodyDecode defaults to none)
2023.05.12 17:04:41.608 5: SMAWR: GetCookies is looking for Cookies
2023.05.12 17:04:41.608 5: SMAWR: ExtractSid called, context sid, num 01
2023.05.12 17:04:41.608 5: SMAWR: Checking SID with JSON access_token
2023.05.12 17:04:41.608 4: SMAWR: checking for redirects, code=400, ignore=0
2023.05.12 17:04:41.608 4: SMAWR: no redirects to handle
2023.05.12 17:04:41.609 5: SMAWR: Read callback sets LAST_REQUEST to auth01
2023-05-12 17:04:41.615 HTTPMOD SMAWR LAST_REQUEST: auth01
2023.05.12 17:04:42.661 5: SMAWR: HandleSendQueue called from Fhem internal timer, qlen = 1
2023.05.12 17:04:42.661 4: SMAWR: HandleSendQueue sends update with timeout 10 to http://mywr/api/v1/plants/Plant:1/devices/IGULD:SELF,
data: {"componentId" : "IGULD:SELF"},
header: Accept: application/json
Authorization: Bearer $sid
Connection: keep-alive
Host: mywr
2023.05.12 17:04:52.664 5: SMAWR: ReadCallback called from HttpUtils_TimeoutErr
2023.05.12 17:04:52.664 5: SMAWR: Read callback Error LogLvl set to 3, regex
2023.05.12 17:04:52.664 3: SMAWR: Read callback: Error: read from http://mywr:80 timed out
2023.05.12 17:04:52.664 4: SMAWR: Read callback: request type was update retry 0, no headers, no body
2023.05.12 17:04:52.665 5: SMAWR: Read callback: body empty
2023.05.12 17:04:52.665 4: SMAWR: BodyDecode is not decoding the response body (charset not found, bodyDecode defaults to none)
2023.05.12 17:04:52.665 5: SMAWR: GetCookies is looking for Cookies
2023.05.12 17:04:52.665 5: SMAWR: ExtractSid called, context reading, num unknown
2023.05.12 17:04:52.665 4: SMAWR: no header to look for redirects
2023.05.12 17:04:52.665 5: SMAWR: Read callback sets LAST_REQUEST to update
2023.05.12 17:04:52.665 5: SMAWR: CheckAuth is checking buffer with ReAuthRegex (?^:ERROR|Error)
2023.05.12 17:04:52.665 5: SMAWR: CheckAuth decided no authentication required
2023-05-12 17:04:52.673 HTTPMOD SMAWR LAST_ERROR: read from http://mywr:80 timed out
2023-05-12 17:04:52.673 HTTPMOD SMAWR LAST_REQUEST: update

Ich bin grad völlig lost...

Kann jemand helfen?

Allen ein schönes Wochenende!
Ronny
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB

betateilchen

Und warum stellst Du Deine Frage nicht im richtigen Unterforum zu HTTPMOD?
Das gehört doch wirklich nicht in die Anfängerfragen.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

FHEMAN

Weil ich über die Suche genau hier ähnliche Fragestellungen und gute Antworten fand, und das Unterforum nicht kannte. Kann ich den Beitrag selbst verschieben?
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB

betateilchen

Am Ende der Seite findest Du einen Button zum Verschieben.

Noch ein grundsätzlicher Tipp: https://forum.fhem.de/index.php?topic=13092.0
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

FHEMAN

Es muss mit der Generierung der SID zu tun haben. Wenn ich im requestHeader eine funktionierende SID aus einer Parallelsession aus dem Browser einfüge, dann bin ich eingeloggt und komme an erste Daten vom WR:

attr mywr requestHeader2 Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2ODM5NzMzOTAsInN1YiI6IkhpbnplTUQiLCJ1aWQiOiI4Njc3NGQ4Yy0xYzRmLTQzOGQtOTNiNS1jYjRjMmFjZDAyZTkiLCJleHAiOjE2ODM5NzY5OTB9.Wp6jX54WV-kpVP5YuAf7lRihT6V1cVUyDXQpKv5wXXx
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB

FHEMAN

#5
Nachdem ich nach vielen Umwegen mithilfe von cURL nun endlich der Lösung näher kam, konnte ich es auch auf HTTPMOD übertragen. Kriegsentscheidend waren die beiden zu ändernden Attribute
attr SMAWR requestData [{"componentId" : "IGULD:SELF"}]
attr SMAWR sid01Data grant_type=password&username=myuser&password=mypassword
Es ist echt frustrierend zu sehen, dass ich so lange kurz vor der Lösung stand.

Hier nun die vollständige Lösung, um einen SMA Tripower X auszulesen (User, Passwort, URL sind anzupassen):
defmod SMAWR HTTPMOD http://smatripower/api/v1/measurements/live 0
attr SMAWR enableControlSet 1
attr SMAWR event-on-change-reading SPOT_.*,INV_.*
attr SMAWR reAuthRegex 401.Unauthorized|500.Server.Error
attr SMAWR reading001Format %.0f
attr SMAWR reading001JSON 03_values_01_values_0
attr SMAWR reading001Name SPOT_UDC1
attr SMAWR reading002Format %.0f
attr SMAWR reading002JSON 03_values_01_values_1
attr SMAWR reading002Name SPOT_UDC2
attr SMAWR reading003Format %.0f
attr SMAWR reading003JSON 03_values_01_values_2
attr SMAWR reading003Name SPOT_UDC3
attr SMAWR reading004Format %.3f
attr SMAWR reading004JSON 02_values_01_values_0
attr SMAWR reading004Name SPOT_IDC1
attr SMAWR reading005Format %.3f
attr SMAWR reading005JSON 02_values_01_values_1
attr SMAWR reading005Name SPOT_IDC2
attr SMAWR reading006Format %.3f
attr SMAWR reading006JSON 02_values_01_values_2
attr SMAWR reading006Name SPOT_IDC3
attr SMAWR reading007Format %.0f
attr SMAWR reading007JSON 01_values_01_values_0
attr SMAWR reading007Name INV_TEMP1
attr SMAWR reading008Format %.0f
attr SMAWR reading008JSON 01_values_01_values_1
attr SMAWR reading008Name INV_TEMP2
attr SMAWR reading009Format %.0f
attr SMAWR reading009JSON 01_values_01_values_2
attr SMAWR reading009Name INV_TEMP3
attr SMAWR reading010Format %.2f
attr SMAWR reading010JSON 07_values_01_value
attr SMAWR reading010Name SPOT_FREQ
attr SMAWR reading011Format %.3f
attr SMAWR reading011JSON 35_values_01_value
attr SMAWR reading011Name SPOT_FEHLERSTROM
attr SMAWR reading012JSON 36_values_01_value
attr SMAWR reading012Name SPOT_ISOLATION
attr SMAWR reading013JSON 44_values_01_value
attr SMAWR reading013Name INV_EVENT
attr SMAWR reading014JSON 48_values_01_value
attr SMAWR reading014Name INV_HEALTH
attr SMAWR reading015JSON 52_values_01_value
attr SMAWR reading015Name INV_STATE
attr SMAWR reading016Format %.0f
attr SMAWR reading016JSON 62_values_01_value
attr SMAWR reading016Name SPOT_PAC
attr SMAWR reading017Format %.0f
attr SMAWR reading017JSON 63_values_01_value
attr SMAWR reading017Name SPOT_PACTOT
attr SMAWR reading017OExpr $val / 1000
attr SMAWR reading018Format %.0f
attr SMAWR reading018JSON 04_values_01_values_0
attr SMAWR reading018Name SPOT_PDC1
attr SMAWR reading019Format %.0f
attr SMAWR reading019JSON 04_values_01_values_1
attr SMAWR reading019Name SPOT_PDC2
attr SMAWR reading020Format %.0f
attr SMAWR reading020JSON 04_values_01_values_2
attr SMAWR reading020Name SPOT_PDC3
attr SMAWR readingMaxAge 600
attr SMAWR readingMaxAgeReplacement 0
attr SMAWR readingMaxAgeReplacementMode text
attr SMAWR requestData [{"componentId":"IGULD:SELF"}]
attr SMAWR requestHeader1 Accept: application/json
attr SMAWR requestHeader2 Content-Type: application/json
attr SMAWR requestHeader3 Authorization: Bearer $sid
attr SMAWR showBody 1
attr SMAWR showError 1
attr SMAWR showMatched 1
attr SMAWR sid1Data grant_type=password&username=myUserMD&password=myPassword
attr SMAWR sid1Header Accept: application/json
attr SMAWR sid1IdJSON access_token
attr SMAWR sid1IgnoreRedirects 0
attr SMAWR sid1URL http://smatripower/api/v1/token
attr SMAWR stateFormat SPOT_PAC (SPOT_PDC1 SPOT_PDC2 SPOT_PDC3) W
attr SMAWR timeout 10

Damit ist es möglich, die einzelnen Strings und verschiedenen Temperatursensoren auszuwerten, was derzeit weder per Modbus noch Speedwire geht.

Gruß
Ronny
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB

blue

Hallo Ronny,

ich bin extrem interessiert an deiner Lösung, habe selbst einen Tripower-WR. Allerdings geht es mir mit deinem Device noch wie dir: Immer Status-Code 400 Bad Request. Vielleicht eine Fragen für Dummy: Was nimmst du denn als Username? Den Sunny Portal-User? Lokal kann ich nur entweder Benutzer oder Installateur wählen, aber was sind dann der Username? Oder muss noch irgendwas auf dem WR einstellen, dass man die API nutzen kann?

Viele Grüße
Kai

FHEMAN

Hallo Kai,

es wird die Website ausgelesen, die der WR lokal bereitstellt. Also nicht das Sunny Portal bzw. Cloud. Das funktioniert out-of-the-box. Rufe mal im Browser die IP oder den DNS deines WR auf und logge dich dort mal ein. Als Installateur oder Benutzer, das müsste egal sein. Username wurde bei mir während der Installation vom Solateur vergeben.
Wenn Benutzer und Passwort funktionieren und Du die WR Seite angezeigt bekommst, trägst Du diese im HTTPMOD Device ein unter

attr HTTPMODDEVICE sid1Data grant_type=password&username=DEINUSERNAME&password=DEINPASSWORT
Viele Grüße
Ronny
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB

FHEMAN

Ich habe festgestellt, dass der WR bei Dunkelheit teils Values, teils ganze Channels weglässt oder anders sortiert. Das gestaltet die Sache mit readingXJSON per ID als schwierig bis unmöglich meiner Meinung nach.

Ich habe daher gewechselt zum guten alten readingXRegex in der Form

Measurement.PvGen.PvW","componentId":"IGULD:SELF","values":\[\{"time":"[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}Z","value":([\d\.]+)\}\]\}
Beispiel für den ersten Wert in Values.
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB