JsonMod response 403 - Ergebnis im Browser aber OK

Begonnen von mthome, 29 Mai 2023, 06:18:56

Vorheriges Thema - Nächstes Thema

mthome

Hallo zusammen,

ich wollte mir die aktuellen Angebote von Rewe per JsonMod abrufen. Leider bekomme ich immer einen "HTTP/1.1 403 Forbidden".

Wenn ich die URL direkt im Browser eingebe bekomme ich den Json   :o

Hat jemand eine Idee an was das liegen kann?

Vielen Dank im Voraus!

Hier das Device List:
Internals:
   API_LAST_MSG invalid server response
   API_LAST_RES 1685333652.70818
   CFGFN     
   DEF        https://mobile-api.rewe.de/api/v3/all-offers?marketCode=240034
   FUUID      6474266b-f33f-6d2a-d178-ca392f8f5724bea7
   NAME       Rewe_Angebote2
   NEXT       2023-05-29 07:00:00
   NR         277
   SOURCE     https://mobile-api.rewe.de/api/v3/all-offers?marketCode=240034 (403)
   STATE      ???
   SVN        27457 2023-04-17 23:35:57 UTC
   TYPE       JsonMod
   eventCount 2
   CONFIG:
     IN_REQUEST 0
     SOURCE     https://mobile-api.rewe.de/api/v3/all-offers?marketCode=240034
     SECRET:
Attributes:
   room       System
   verbose    5

Und hier der Log-Auszug:
2023.05.29 06:14:12 5: HttpUtils url=https://mobile-api.rewe.de/api/v3/all-offers?marketCode=240034 NonBlocking via https
2023.05.29 06:14:12 4: IP: mobile-api.rewe.de -> 104.16.64.9
2023.05.29 06:14:12 5: HttpUtils request header:
GET /api/v3/all-offers?marketCode=240034 HTTP/1.0
Host: mobile-api.rewe.de
User-Agent: fhem
Accept-Encoding: gzip,deflate

Accept: application/json
Accept-Charset: utf-8, iso-8859-1

2023.05.29 06:14:12 4: https://mobile-api.rewe.de/api/v3/all-offers?marketCode=240034: HTTP response code 403
2023.05.29 06:14:12 5: HttpUtils https://mobile-api.rewe.de/api/v3/all-offers?marketCode=240034: Got data, length: 16
2023.05.29 06:14:12 5: HttpUtils response header:
HTTP/1.1 403 Forbidden
Date: Mon, 29 May 2023 04:14:12 GMT
Content-Type: text/plain; charset=UTF-8
Content-Length: 16
Connection: close
X-Frame-Options: SAMEORIGIN
Referrer-Policy: same-origin
Cache-Control: private, max-age=0, no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Expires: Thu, 01 Jan 1970 00:00:01 GMT
Set-Cookie: __cf_bm=73HquY_NQbvKIWa0dtC2xKt925JKZsJKdrzd2GxyCCg-1685333652-0-AYCjnKKRAcEl9TKMOOrCP+hTl8joWku/PMJ9bf+7i3lm3cr3FX2UmzjnlptyQ0nVMSi2Kpnmjn/fibau+rp20Cs=; path=/; expires=Mon, 29-May-23 04:44:12 GMT; domain=.rewe.de; HttpOnly; Secure; SameSite=None
Vary: Accept-Encoding
Strict-Transport-Security: max-age=15552000
Server: cloudflare
CF-RAY: 7cebe8c14d7a9279-FRA
2023.05.29 06:14:12 4: [Rewe_Angebote2] api encoding is UTF-8, designated encoder is utf-8-strict
2023.05.29 06:14:12 5: [Rewe_Angebote2] start json decoding

betateilchen

Was Du im Browser siehst, ist nicht das direkte Ergebnis der URL-Anfrage.
Deshalb kannst Du nicht davon ausgehen, dass das Ergebnis im Browser mit dem Ergebnis einer direkten URL-Abfrage übereinstimmt - da spielen noch andere Faktoren mit, möglicherweise angefangen vom User-Agent über Session Cookies oder was auch immer.

Wenn Du den Aufruf manuell auf einer Konsole machst, passiert genau das gleiche, was Du in Deinem JsonMod device siehst:

wget https://mobile-api.rewe.de/api/v3/all-offers?marketCode=240034
--2023-05-30 10:18:46--  https://mobile-api.rewe.de/api/v3/all-offers?marketCode=240034
Resolving mobile-api.rewe.de (mobile-api.rewe.de)... 2606:4700::6810:4009, 2606:4700::6810:4109, 104.16.65.9, ...
Connecting to mobile-api.rewe.de (mobile-api.rewe.de)|2606:4700::6810:4009|:443... connected.
HTTP request sent, awaiting response... 403 Forbidden
2023-05-30 10:18:46 ERROR 403: Forbidden.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

mthome

#2
OK, vielen Dank. Was heißt das?

Ich hatte bereits probiert im Attribut httpHeader mit User-Agent weiter zu kommen. Habe die Info aus dem Browser eingetragen. Hatte aber leider nichts gebracht.

Wenn ich z.B. auf der Console folgenden curl Befehl eingebe geht es auch. Ist dann aber vermutlich auch das gleiche wie über Browser? Habe mal mit Verbose eingestellt - ist da was dabei was mir helfen würde?

curl -G -v  "https://mobile-api.rewe.de/api/v3/all-offers?marketCode=240034"
*   Trying 2606:4700::6810:4009:443...
* TCP_NODELAY set
* Connected to mobile-api.rewe.de (2606:4700::6810:4009) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Request CERT (13):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Certificate (11):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=US; ST=California; L=San Francisco; O=Cloudflare, Inc.; CN=rewe.de
*  start date: Apr  1 00:00:00 2023 GMT
*  expire date: Mar 31 23:59:59 2024 GMT
*  subjectAltName: host "mobile-api.rewe.de" matched cert's "*.rewe.de"
*  issuer: C=US; O=Cloudflare, Inc.; CN=Cloudflare Inc ECC CA-3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x5592c16f8320)
> GET /api/v3/all-offers?marketCode=240034 HTTP/2
> Host: mobile-api.rewe.de
> user-agent: curl/7.68.0
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Connection state changed (MAX_CONCURRENT_STREAMS == 256)!
< HTTP/2 200
< date: Tue, 30 May 2023 10:47:31 GMT
< content-type: application/json; charset=utf-8
< server-timing: intid;desc=4205dc9524cc7eea
< x-powered-by: hantayo/2.0.17-master-8507/-1
< ruleversion: 1
< traceparent: 00-00000000000000004205dc9524cc7eea-29fc1ccbc59a1f3e-01
< tracestate: in=4205dc9524cc7eea;29fc1ccbc59a1f3e
< x-instana-l: 1
< x-instana-s: 29fc1ccbc59a1f3e
< x-instana-t: 4205dc9524cc7eea
< etag: W/"36412-yqOJ6wo0lKiPi2Tlf3c0JCZ5W5Q"
< vary: Accept-Encoding
< via: 1.1 google
< cf-cache-status: DYNAMIC
< set-cookie: __cf_bm=kp_ovz5gXI8VE_O6JiaMDLnOrMjxOrwY_9cW7vCN7pU-1685443651-0-ASQ+TiZusS+NsBYlfBwF7RREQDRzlv/POkR99fDYrYYButrS1OnEBzF6gxmgT/R+gzOTUZVVbaSqGI1Q2Y7I9L0=; path=/; expires=Tue, 30-May-23 11:17:31 GMT; domain=.rewe.de; HttpOnly; Secure; SameSite=None
< strict-transport-security: max-age=15552000
< set-cookie: _cfuvid=TBZY9_rx0QeVl.zUEH_yUtNN_lcrUWeXYFA4v9b947I-1685443651072-0-604800000; path=/; domain=.rewe.de; HttpOnly; Secure; SameSite=None
< server: cloudflare
< cf-ray: 7cf66642d96c18d8-FRA
<
<
{....ab hier kommt das Json}

Bedeutet das, ich muss mich davon verabschieden es mit JsonMod zu machen?

ch.eick

Moin,
manchmal liegt es auch an der falschen HTTP Version.

im ersten Post sieht man HTTP/1.0 und beim curl wird HTTP/1.1 verwendet.
Dafür gibt es im Device ein Attribut, nur mal so zum testen.

VG  Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

Wernieman

#4
Also am UserAgent liegt es nicht ....

Frage mich gerade: Was macht curl anders als wget??

Edit:
an http/1.1 liegt es nicht ... jedenfalls nicht bei wget
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

betateilchen

* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x5592c16f8320)
> GET /api/v3/all-offers?marketCode=240034 HTTP/2

Zitat von: Wernieman am 30 Mai 2023, 16:15:45Frage mich gerade: Was macht curl anders als wget??

curl unterstützt HTTP2, wget nicht.

Testet man das ganze mit wget2 (wget mit HTTP2 support) funktioniert es auch.

wget2 https://mobile-api.rewe.de/api/v3/all-offers?marketCode=240034
[0] Downloading 'https://mobile-api.rewe.de/api/v3/all-offers?marketCode=240034' ...
Saving 'all-offers?marketCode=240034'
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

#6
Zitat von: mthome am 30 Mai 2023, 11:38:00OK, vielen Dank. Was heißt das?
...
Bedeutet das, ich muss mich davon verabschieden es mit JsonMod zu machen?

Ein möglicher Workaround wäre:
Per cronjob den Seiteninhalt abholen und in eine Textdatei schreiben, dann mit FHEM und JsonMod diese Textdatei verarbeiten.

Aber Vorsicht: das ergibt mit complete() im Moment fast 4500 readings!

defmod rewe JsonMod file://tmp/rewe.json
attr rewe readingList complete()

...
setstate rewe 2023-05-30 17:42:00 hasOnlineOffers 1
setstate rewe 2023-05-30 17:42:00 untilDate 1685750400000

Du darfst diesen Dateianhang nicht ansehen.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

herrmannj

Muss ja nicht per complete()

Problem ist also die fehlende http2 Unterstützung fhem, korrekt?

betateilchen

#8
Zitat von: herrmannj am 30 Mai 2023, 18:32:55Muss ja nicht per complete()

Stimmt, aber ich hatte vorhin keine Lust, mich durch die Struktur zu wühlen, mir ging es eher darum, ob das json überhaupt korrekt verarbeitet werden kann. Ausserdem weiß ich ja nicht, welche readings der Fragesteller tatsächlich braucht/haben möchte.

defmod rewe JsonMod file://tmp/rewe.json
attr rewe readingList single(jsonPath('$.categories.0.offers.0.title'),'artikeltext','?')\
single(jsonPath('$.categories.0.offers.0.subtitle'),'zusatztext','?')\
single(jsonPath('$.categories.0.offers.0.priceData.price'),'preis','?')

setstate rewe 2023-05-30 19:26:04 .computedReadings artikeltext,preis,zusatztext
setstate rewe 2023-05-30 19:26:04 artikeltext Géramont Cremig-zarte Scheiben
setstate rewe 2023-05-30 19:26:04 preis 1,99 €
setstate rewe 2023-05-30 19:26:04 zusatztext je 150-g-Pckg. (1 kg = 13.27)

Wem es schmeckt... 8)

Zitat von: herrmannj am 30 Mai 2023, 18:32:55Problem ist also die fehlende http2 Unterstützung fhem, korrekt?

Es deutet zumindest vieles darauf hin.

offtopic: kommst Du nächste Woche zum Stammtisch?
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Wernieman

@betateilchen

Danke für die Info. Wußte gar nicht, das es ein wget2 gibt .... man lernt nicht aus ...
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

herrmannj


mthome

Zitat von: betateilchen am 30 Mai 2023, 17:37:03Ein möglicher Workaround wäre:
Per cronjob den Seiteninhalt abholen und in eine Textdatei schreiben, dann mit FHEM und JsonMod diese Textdatei verarbeiten.

Vielen Dank für den Workaround - dann werde ich es wohl so angehen. Mir reichen eigentlich alle "Topangebote" und deren Preis, die ich dann per Sprache an einem Echolautsprecher durchsagen lasse.

Der Hintergrund ist, dass mein Vater nicht mehr viel sehen kann, ich ihm aber ermöglichen möchte, dass er sich Angebote vorlesen lassen kann.

Nachmals Danke für Eure Hilfe!

betateilchen

Nur die Topangebote, bitteschön...
defmod rewe JsonMod file://tmp/rewe.json
attr rewe readingList multi(jsonPath('$.categories.0.offers.[*]'),concat('artikeltext_', count()),property('title'))\
multi(jsonPath('$.categories.0.offers.[*]'),concat('zusatztext_', count()),property('subtitle'))\
multi(jsonPath('$.categories.0.offers.[*]'),concat('preis_', count()),property('priceData.price'))
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

herrmannj

ich denke darüber nach, dass via JsonMod zugänglich zu machen. Noch nicht ausformuliert aber von der Idee her: analog zu file:// saw etwas wie shell:// oder system:// - Das so aufgerufene script würde dann idealerweise per pipe oder vergleichbar einen gültigen Json payload zurückgeben. Dann hätte man die ganzen "Sonderfälle" (POST, PUT, DELETE, irgendwelche Tokens etc oder OAUTH) alle ausgelagert. Da darf sich dann nach belieben bedient werden aber der "workflow" (cron, fehlerbehandlung etc) bleibt geradlinig im modul ...

betateilchen

Ob sich der Aufwand lohnt?
Bisher löse ich das einfach wie hier beschrieben:

  • Daten per cron abholen und in Datei schreiben
  • nach dem Holen der Daten wird aus dem gleichen Skript per telnet ein "set jsonmod-device reread" ausgelöst, um den Kram in readings zu verwursten.

Funktioniert einwandfrei und zuverlässig.

Und der cron auf Betriebssystemeben funktioniert vollumfänglich...
*duck-und-weg*

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

herrmannj

Bitte das file im Anhang testen. Du darfst diesen Dateianhang nicht ansehen.

Für die def: alles was nach system:// kommt, wird als system Aufruf interpretiert. Das kann alles sein (hier curl), Hauptsache ein vernünftiger json kommt zurück. Damit geht jetzt auch POST, DELETE etc (per curl)

define json_system JsonMod system://curl https://mobile-api.rewe.de/api/v3/all-offers?marketCode=240034
attr json_system readingList multi(jsonPath('$.categories.0.offers.[*]'),concat('artikeltext_', count()),property('title'));;
#   API_LAST_MSG -1
#   API_LAST_RES 1685488908.77475
#   DEF        system://curl https://mobile-api.rewe.de/api/v3/all-offers?marketCode=240034
#   FUUID      64766901-f33f-a34f-a0f4-ff25f695591bd6fc
#   NAME       json_system
#   NEXT       2023-05-31 02:00:00
#   NR         47
#   SOURCE      (-1)
#   STATE      ???
#   SVN        27457 2023-04-17 23:35:57 UTC
#   TYPE       JsonMod
#   eventCount 8
#   CONFIG:
#     IN_REQUEST 0
#     SOURCE     system://curl https://mobile-api.rewe.de/api/v3/all-offers?marketCode=240034
#     SECRET:
#   READINGS:
#     2023-05-31 01:21:48   artikeltext_0   Géramont Cremig-zarte Scheiben
#     2023-05-31 01:21:48   artikeltext_1   Géramont Weichkäse
#     2023-05-31 01:21:48   artikeltext_10  Bizzl Apfelschorle oder Limonade
#     2023-05-31 01:21:48   artikeltext_11  Mini Roma Rispentomaten
#     2023-05-31 01:21:48   artikeltext_12  REWE �Beste Wahl Anno 1904 Weizenmischbrot
#     2023-05-31 01:21:48   artikeltext_13  Jacobs Auslese oder Meisterröstung
#     2023-05-31 01:21:48   artikeltext_14  Schweine-Rückensteaks
#     2023-05-31 01:21:48   artikeltext_15  Volvic Naturelle
#     2023-05-31 01:21:48   artikeltext_2   Barilla Pasta
#     2023-05-31 01:21:48   artikeltext_3   Vorgereifte Avocado
#     2023-05-31 01:21:48   artikeltext_4   Frisches Hähnchen-Brustfilet
#     2023-05-31 01:21:48   artikeltext_5   Coca-Cola
#     2023-05-31 01:21:48   artikeltext_6   Leerdammer Original
#     2023-05-31 01:21:48   artikeltext_7   Schöller Multipackung Kaktus
#     2023-05-31 01:21:48   artikeltext_8   Schöller Multipackung Pirulo Watermelon
#     2023-05-31 01:21:48   artikeltext_9   Steinhaus Krustenbraten oder Krustenbraten Thymian-Honig
#
setstate json_system 2023-05-31 01:21:48 .computedReadings artikeltext_6,artikeltext_1,artikeltext_13,artikeltext_2,artikeltext_11,artikeltext_7,artikeltext_8,artikeltext_10,artikeltext_15,artikeltext_3,artikeltext_9,artikeltext_5,artikeltext_4,artikeltext_12,artikeltext_0,artikeltext_14
setstate json_system 2023-05-31 01:21:48 artikeltext_0 Géramont Cremig-zarte Scheiben
setstate json_system 2023-05-31 01:21:48 artikeltext_1 Géramont Weichkäse
setstate json_system 2023-05-31 01:21:48 artikeltext_10 Bizzl Apfelschorle oder Limonade
setstate json_system 2023-05-31 01:21:48 artikeltext_11 Mini Roma Rispentomaten
setstate json_system 2023-05-31 01:21:48 artikeltext_12 REWE �Beste Wahl Anno 1904 Weizenmischbrot
setstate json_system 2023-05-31 01:21:48 artikeltext_13 Jacobs Auslese oder Meisterröstung
setstate json_system 2023-05-31 01:21:48 artikeltext_14 Schweine-Rückensteaks
setstate json_system 2023-05-31 01:21:48 artikeltext_15 Volvic Naturelle
setstate json_system 2023-05-31 01:21:48 artikeltext_2 Barilla Pasta
setstate json_system 2023-05-31 01:21:48 artikeltext_3 Vorgereifte Avocado
setstate json_system 2023-05-31 01:21:48 artikeltext_4 Frisches Hähnchen-Brustfilet
setstate json_system 2023-05-31 01:21:48 artikeltext_5 Coca-Cola
setstate json_system 2023-05-31 01:21:48 artikeltext_6 Leerdammer Original
setstate json_system 2023-05-31 01:21:48 artikeltext_7 Schöller Multipackung Kaktus
setstate json_system 2023-05-31 01:21:48 artikeltext_8 Schöller Multipackung Pirulo Watermelon
setstate json_system 2023-05-31 01:21:48 artikeltext_9 Steinhaus Krustenbraten oder Krustenbraten Thymian-Honig


mthome

#16
Hallo herrmannj,

funktioniert super! Vieelen vieelen Dank

Internals:
   API_LAST_MSG -1
   API_LAST_RES 1685505418.77012
   CFGFN     
   DEF        system://curl https://mobile-api.rewe.de/api/v3/all-offers?marketCode=240034
   FUUID      6476c3d2-f33f-6d2a-2420-4c551122bf8b045c
   NAME       ReweTest
   NEXT       2023-05-31 06:00:00
   NR         3744
   SOURCE      (-1)
   STATE      ???
   SVN        27457 2023-04-17 23:35:57 UTC
   TYPE       JsonMod
   eventCount 6
   CONFIG:
     IN_REQUEST 0
     SOURCE     system://curl https://mobile-api.rewe.de/api/v3/all-offers?marketCode=240034
     SECRET:
   READINGS:
     2023-05-31 05:56:58   artikeltext_0   Géramont Cremig-zarte Scheiben
     2023-05-31 05:56:58   artikeltext_1   Géramont Weichkäse
     2023-05-31 05:56:58   artikeltext_10  Bizzl Apfelschorle oder Limonade
     2023-05-31 05:56:58   artikeltext_11  Mini Roma Rispentomaten
     2023-05-31 05:56:58   artikeltext_12  REWE �Beste Wahl Anno 1904 Weizenmischbrot
     2023-05-31 05:56:58   artikeltext_13  Jacobs Auslese oder Meisterröstung
     2023-05-31 05:56:58   artikeltext_14  Schweine-Rückensteaks
     2023-05-31 05:56:58   artikeltext_15  Volvic Naturelle
     2023-05-31 05:56:58   artikeltext_2   Barilla Pasta
     2023-05-31 05:56:58   artikeltext_3   Vorgereifte Avocado
     2023-05-31 05:56:58   artikeltext_4   Frisches Hähnchen-Brustfilet
     2023-05-31 05:56:58   artikeltext_5   Coca-Cola
     2023-05-31 05:56:58   artikeltext_6   Leerdammer Original
     2023-05-31 05:56:58   artikeltext_7   Schöller Multipackung Kaktus
     2023-05-31 05:56:58   artikeltext_8   Schöller Multipackung Pirulo Watermelon
     2023-05-31 05:56:58   artikeltext_9   Steinhaus Krustenbraten oder Krustenbraten Thymian-Honig
     2023-05-31 05:56:58   preis_0         1,99 €
     2023-05-31 05:56:58   preis_1         1,99 €
     2023-05-31 05:56:58   preis_10        8,49 €
     2023-05-31 05:56:58   preis_11        1,49 €
     2023-05-31 05:56:58   preis_12        1,79 €
     2023-05-31 05:56:58   preis_13        3,99 €
     2023-05-31 05:56:58   preis_14        2,99 €
     2023-05-31 05:56:58   preis_15        4,74 €
     2023-05-31 05:56:58   preis_2         0,99 €
     2023-05-31 05:56:58   preis_3         0,79 €
     2023-05-31 05:56:58   preis_4         8,80 €
     2023-05-31 05:56:58   preis_5         0,95 €
     2023-05-31 05:56:58   preis_6         0,88 €
     2023-05-31 05:56:58   preis_7         2,22 €
     2023-05-31 05:56:58   preis_8         2,22 €
     2023-05-31 05:56:58   preis_9         1,79 €
Attributes:
   group      Test
   readingList multi(jsonPath('$.categories.0.offers.[*]'),concat('artikeltext_', count()),property('title'));
multi(jsonPath('$.categories.0.offers.[*]'),concat('preis_', count()),property('priceData.price'));

   room       System

Hast Du vor, diese Änderung auch zu veröffentlichen? Dann würde ich mir die Cronjob Geschichte sparen  ;D

herrmannj


ch.eick

Hey,

ich habe mal raus gesucht, wie man den marketcode abfragen kann :-)

https://www.rewe.de/api/marketsearch?searchTerm=<PLZ>

wwIdent "marketcode"
isReweDortmund false
companyName "REWE Markt GmbH"
contactStreet "Strasse"
contactZipCode "PLZ"
contactCity "Ort"
marketHeadline "REWE Markt"
openingInfo
isOpen
until "22:00"

VG  Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

herrmannj

Ich bin gerade etwas ratlos, jemand eine Idee zu: (?)

https://reqbin.com/req/c-dwjszac0/curl-post-json-example

erlaubt es den (POST) request zu testen, das wollte ich gerade mit POST+Json (+ unit test und Doku für JsonMod). Wenn ich den request online (via link) teste, dann geht das. Ich bekomme das aber lokal (cmdline, verschiedene OS) nicht zum laufen, ich bekomme da immer HTML zurück.

Dies:
curl -X POST https://reqbin.com/echo/post/json
   -H 'Content-Type: application/json'
   -d '{"login":"my_login","password":"my_password"}'
sollte das ergeben:
{
    "success": "true"
}

Jemand 'ne Idee ?

herrmannj

Zitat von: mthome am 31 Mai 2023, 06:02:13system://curl https://mobile-api.rewe.de/api/v3/all-offers?marketCode=240034

ich hab dir mal die readingList in noch etwas schöner [sic] gemacht:
multi(jsonPath('$.categories.0.offers.[*]'), property('detail.contents.0.titles.0'), sprintf('%s (%s) nur %s', property('title'), property('subtitle'), property('priceData.price')));

Art.-Nr._1178278
Vorgereifte Avocado (»Hass«, Kl. I, je St.) nur 0,79 €
2023-05-31 22:22:37
Art.-Nr._1223984
Bizzl Apfelschorle oder Limonade (versch. Sorten, teilw. koffeinhaltig, je 12 x 1-l-Fl.-Kasten (1 l = 0.71), zzgl. 3.30 Pfand) nur 8,49 €
2023-05-31 22:22:37
Art.-Nr._1483021
Barilla Pasta (versch. Ausformungen, je 500-g-Pckg. (1 kg = 1.98)) nur 0,99 €
2023-05-31 22:22:37
Art.-Nr._2018980
Steinhaus Krustenbraten oder Krustenbraten Thymian-Honig (Haltungsform 2, je 100 g) nur 1,79 €
2023-05-31 22:22:37
Art.-Nr._2255510
Géramont Cremig-zarte Scheiben (je 150-g-Pckg. (1 kg = 13.27)) nur 1,99 €
2023-05-31 22:22:37
Art.-Nr._2345396
Schweine-Rückensteaks (in versch. Marinaden, Haltungsform 2, je 300-g-Pckg. (1 kg = 9.97)) nur 2,99 €
2023-05-31 22:22:37
Art.-Nr._263357
Volvic Naturelle (je 6 x 1,5-l-Fl.-Pckg. (1 l = 0.53), zzgl. 1.50 Pfand) nur 4,74 €
2023-05-31 22:22:37
Art.-Nr._2713121
Schöller Multipackung Kaktus (je 9 x 45-ml-Pckg. (1 l = 5.48)) nur 2,22 €
2023-05-31 22:22:37
Art.-Nr._4508467
Leerdammer Original (holl. Schnittkäse, 45% Fett i.Tr., je 100 g) nur 0,88 €
2023-05-31 22:22:37
Art.-Nr._4529243
Géramont Weichkäse (60% Fett i.Tr., je 200-g-Pckg. (1 kg = 9.95)) nur 1,99 €
2023-05-31 22:22:37
Art.-Nr._6730574
Coca-Cola (versch. Sorten, teilw. koffeinhaltig, je 1,5-l-Fl. (1 l = 0.63), zzgl. 0.25 Pfand) nur 0,95 €
2023-05-31 22:22:37
Art.-Nr._7055901
Jacobs Auslese oder Meisterröstung (versch. Sorten, gemahlener Bohnenkaffee, je 500-g-Pckg. (1 kg = 7.98)) nur 3,99 €
2023-05-31 22:22:37
Art.-Nr._7238775
Mini Roma Rispentomaten (»Aromatica«, Kl. I, je 250-g-Schale (1 kg = 5.96)) nur 1,49 €
2023-05-31 22:22:37
Art.-Nr._7556390
Frisches Hähnchen-Brustfilet (Teilstück, Haltungsform 2, SB-verpackt, je 1 kg) nur 8,80 €
2023-05-31 22:22:37
Art.-Nr._7662860
REWE �Beste Wahl Anno 1904 Weizenmischbrot (je 500-g-Pckg. (1 kg = 3.58)) nur 1,79 €
2023-05-31 22:22:37
Art.-Nr._8255247
Schöller Multipackung Pirulo Watermelon (je 5 x 73-ml-Pckg. (1 l = 6.08)) nur 2,22 €
2023-05-31 22:22:37

betateilchen

Zitat von: herrmannj am 31 Mai 2023, 21:43:49Ich bin gerade etwas ratlos, jemand eine Idee zu:


Spontan (kann gerade nicht testen) würde ich sagen, da fehlt ein accept header, in dem drinsteht, dass Du json als Antwort möchtest.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

#22
Was von reqbin als html zurückkommt, ist ja letztlich eine Fehlerseite wegen fehlenden Cookies und nicht vorhandenem JavaScript. Vermutlich ist die Seite nicht dafür gedacht, von außerhalb eines echten Browsers aufgerufen zu werden.

Probier es mal mit einer anderen Testumgebung  :)

curl -X POST "https://httpbin.org/anything" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"login":"my_login","password":"my_password"}'
liefert als Antwort:

{
  "args": {},
  "data": "{\"login\":\"my_login\",\"password\":\"my_password\"}",
  "files": {},
  "form": {},
  "headers": {
    "Accept": "application/json",
    "Content-Length": "45",
    "Content-Type": "application/json",
    "Host": "httpbin.org",
    "User-Agent": "curl/7.74.0",
    "X-Amzn-Trace-Id": "Root=...4f8"
  },
  "json": {
    "login": "my_login",
    "password": "my_password"
  },
  "method": "POST",
  "origin": "myIP",
  "url": "https://httpbin.org/anything"
}
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

herrmannj

Zitat von: betateilchen am 01 Juni 2023, 00:20:19Was von reqbin als html zurückkommt, ist ja letztlich eine Fehlerseite wegen fehlenden Cookies und nicht vorhandenem JavaScript. Vermutlich ist die Seite nicht dafür gedacht, von außerhalb eines echten Browsers aufgerufen zu werden.
vmtl die einfachste Erklärung. Wusste nicht, dass das mit httpbin auch geht. Perfekt, Danke. Das reicht für einen unit test mehr als aus.

kurt6908

Hallo,

ich nutze JsonMod um eine lokale XML-Datei auszulesen. Seit dem letzen Update auf die neue Version (Revision 27640) funtkioniert aber mein file:/ als source nicht mehr. Verzeichnisseitig wurde nicht geändert, nur das nächtliche Update hat das Update eingespielt. Letzer erfolgreicher Leseversuch, war der letze vorm Update.

Kann jemand das Problem lösen oder mir einen Ratschlag geben???

Vielen Dank.

Kurt
3* Raspberry Pi (2 über LTE/VPN), 5* Cul, 3* FS20, 4* FHT, 6* HM, Somfy, Solarlog, WMBus/EnergyCam, AVM FritzBox, 3* AVM Powerline, Alexa, Tasmota/MQTT, Rademacher DuoFern, EPEver HiPower/ModBus, go-eCharger

herrmannj

Ja gern. Zeig Mal deine def bitte   

Btw, bitte beim nächsten Mal für so etwas einen neuen Thread bitte

kurt6908

Hallo,

hab exra keinen neuen Thread aufgemacht, da es nach meiner Ansicht mit dem Update zusammenhängt. Aber beim nächsten Mal denke ich daran.

Hier mein Device:

Internals:
   API_LAST_MSG 404
   API_LAST_RES 1686065111.2714
   DEF        file://home/pi/a4:c1:38:c8:8f:6d.json
   FUUID      60ddf128-f33f-c3f9-dc53-c3f7d24259b838c6
   NAME       Garage_Batterie1
   NEXT       2023-06-06 17:30:00
   NR         64
   SOURCE     home/pi/a4:c1:38:c8:8f:6d.json
   STATE      2023-06-06_03:50:05
   SVN        27640 2023-06-01 17:03:20 UTC
   TYPE       JsonMod
   eventCount 9
   CONFIG:
     IN_REQUEST 0
     SOURCE     file://home/pi/a4:c1:38:c8:8f:6d.json
     SECRET:
   READINGS:
     2023-06-06 03:55:00   Imain           -0.35
     2023-06-06 03:55:00   NominalCap      110
     2023-06-06 03:55:00   NumberCycles    180
     2023-06-06 03:55:00   ProtectState    0
     2023-06-06 03:55:00   ProtectStateText ok
     2023-06-06 03:55:00   RemainCap       70.85
     2023-06-06 03:55:00   SOC             64
     2023-06-06 03:55:00   Temp            24.8
     2023-06-06 03:55:00   Time            2023-06-06_03:50:05
     2023-06-06 03:55:00   Vmain           26.28
Attributes:
   event-on-change-reading .*
   interval   */5 * * * *
   readingList single(jsonPath('$.Vmain'), 'Vmain', '0'); single(jsonPath('$.Imain'), 'Imain', '0'); single(jsonPath('$.SOC'), 'SOC', '0'); single(jsonPath('$.NominalCap'), 'NominalCap', '0'); single(jsonPath('$.RemainCap'), 'RemainCap', '0'); single(jsonPath('$.Time'), 'Time', '0'); single(jsonPath('$.NumberCycles'), 'NumberCycles', '0'); single(jsonPath('$.ProtectState'), 'ProtectState', '0'); single(jsonPath('$.ProtectStateText'), 'ProtectStateText', '0'); single(jsonPath('$.Temp'), 'Temp', '0')
   room       Energie
   stateFormat {ReadingsVal($name,"Time",undef)}

Um 04:00 lief das FHEM-Update. Die auszulende Datei hat aktuelle Werte, die FHEM-Readings zeigen die Werte vor 04:00.

Unter Source habe ich es auch mit 'file:/' (also nur ein /) probiert, aber geht auch nicht.

Viele Grüße

Kurt
3* Raspberry Pi (2 über LTE/VPN), 5* Cul, 3* FS20, 4* FHT, 6* HM, Somfy, Solarlog, WMBus/EnergyCam, AVM FritzBox, 3* AVM Powerline, Alexa, Tasmota/MQTT, Rademacher DuoFern, EPEver HiPower/ModBus, go-eCharger

herrmannj

bei absoluten path müssen 3 "/" hin.

Du hast Recht, theoretisch müsste ein "/" ebenfalls funktionieren. Um keine breaking changes zu erzeugen, lasse ich das vorerst aber so wie es ist.

betateilchen

Probiers mal mit

file:///home/pi/a4:c1:38:c8:8f:6d.json
JsonMod regext (seit neuestem) sowohl einen als auch zwei slashes gnadenlos weg.
Deshalb funktionieren absolute Pfade mit / am Anfang nicht mehr, weil aus Deiner Angabe dann

home/pi/...
wird, was logischerweise nicht als Datei gefunden wird.
Mit drei slashes bleibt nach dem regex einer übrig, dann funktioniert auch die Auswertung wieder.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

#29
Zitat von: herrmannj am 06 Juni 2023, 20:27:32Um keine breaking changes zu erzeugen, lasse ich das vorerst aber so wie es ist.

Das neue Verhalten IST aber ein breaking change. Ich musste jetzt seit dem Update auch 3 slashes verwenden, was vorher nicht notwendig war.

Zitat von: herrmannj am 06 Juni 2023, 20:27:32theoretisch müsste ein "/" ebenfalls funktionieren

praktisch auch, wenn man Deinem Code Glauben schenken darf.

# file: correct file:/.. but also accepted file://..
if ($source =~ m/^file:[\/]{1,2}(.+)/) {
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

kurt6908

Hallo,

vielen Dank ... jetzt funzt es wieder.

Kleine Korrektur in der Hilfe

Zitatdefines the device and set the source (file:/|http://|https://).

für das Modul wäre aus meiner Sicht jetzt wünscheswert ;=)

Viele Grüße

Kurt

3* Raspberry Pi (2 über LTE/VPN), 5* Cul, 3* FS20, 4* FHT, 6* HM, Somfy, Solarlog, WMBus/EnergyCam, AVM FritzBox, 3* AVM Powerline, Alexa, Tasmota/MQTT, Rademacher DuoFern, EPEver HiPower/ModBus, go-eCharger

herrmannj

#31
Zitatpraktisch auch, wenn man Deinem Code Glauben schenken darf.
leider nur relativ, nicht absolut.

Korrekt wäre das so:
https://en.wikipedia.org/wiki/File_URI_scheme

absolut:
file:///home/bla
file:/home/bla

relativ (nicht norm aber gebräuchlich)
file:log/bla
file:./log/bla

Die Fälle #1,#3,#4 funktionieren auch genau so.

Wenn das ne große Sache für euch ist, kann ich das nochmal anpassen. Den "file://log" gibt es offiziell nicht, den setze ich dann auf relativ um. (Aus file://log/bla wird file:log/bla , ergo relativ)


betateilchen

Naja, vorher hat es halt mit 2 // auch mit /tmp/file.json funktioniert, das tut es jetzt nicht mehr.

Entscheide Dich einfach für EINE einheitliche Syntax oder gib nicht einfach kommentarlos eine 404 aus, die niemand interpretieren kann, nur weil das device plötzlich die Datei nicht mehr findet. Vielleicht wäre eine Logmeldung sinnvoll, die auf die 3 /// hinweist, die neuerdings gebraucht werden.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

herrmannj

#33
ich habe fall #2 ergänzt und file-uri Beispiele (abs+rel) in die Doku genommen

dadoc

Hallo zusammen,
seit einem Jahr hole ich mit einem "kunstvollen" Konstrukt Wetterdaten der spanischen Wetterbehörde aemet per JSONMOD ab. Seit ein paar Tagen klappt das nicht mehr, s.u. Ich habe m.W. nichts verändert, außer apache2 und php7 vom Raspi zu deinstallieren, auf dem auch fhem läuft. Aber das sollte AFAIK keine Auswirkungen auf JSONMOD haben?
Mit estemp hole ich periodisch eine URL ab, die die eigentlichen Wetterdaten enthält (API Key gekürzt mit ...):
Internals:
  API_LAST_MSG read from https://opendata.aemet.es:443 timed out
  API_LAST_RES 1689256534.00405
  DEF        https://opendata.aemet.es/opendata/api/prediccion/especifica/municipio/diaria/07021/?api_key= eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJtLmtuYXB...
  FUUID      62dff765-f33f-04c7-33d8-14908c3a406dd351
  NAME      estemp
  NEXT      2023-07-13 16:00:00
  NR        363
  SOURCE    https://opendata.aemet.es/opendata/api/prediccion/especifica/municipio/diaria/07021/?api_key= eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJtLmtuYXB... ()
  STATE      ???
  SVN        27660 2023-06-06 20:03:18 UTC
  TYPE      JsonMod
  eventCount 4
  CONFIG:
    IN_REQUEST 1
    SOURCE    https://opendata.aemet.es/opendata/api/prediccion/especifica/municipio/diaria/07021/?api_key= eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJtLmtuYXB...
    SECRET:
  READINGS:
    2023-07-10 00:24:00  aemet_url2      https://opendata.aemet.es/opendata/sh/c6ca4b1d
    2023-07-10 00:24:00  aemet_validity_status exito
Attributes:
  disable    0
  httpHeader X-API-Key: [KEY]
  httpTimeout 50
  interval  */4 * * * *
  readingList single(jsonPath('datos'), 'aemet_url2', 'N/A');
single(jsonPath('descripcion'), 'aemet_validity_status', 'N/A');

  room      Wetter,aemet

Resultat ist wie zu sehen
API_LAST_MSG
read from https://opendata.aemet.es:443 timed out
Rufe ich die URL aus der DEF manuell im Browser auf, klappt alles.
Habe jetzt nach fhem Update die neuen Pfad-Beispiele in der Device Help gesehen:
Define
define <name> JsonMod <http[s]:example.com:/somepath/somefile.json>
Soll das wirklich so, also ohne Slashes?
Geht bei mir jedenfalls auch nicht (URL Error als Response).
Habt Ihr eine Ahnung, was sich da geändert haben könnte bzw. ob das auf meiner Seite ist oder bei aemet?
Danke & Grüße
Martin

Standort 1: FS20 mit CUL und FHEM auf Raspi. HM-Komponenten (Heizung, Rollladen, Schalter). HM IP über Raspimatic (testweise)
Standort 2: Homematic (Wired) über CCU2 und PocketHome HD
3 x Raspi3 mit piCorePlayer/Kodi für Multiroom Audio (+ Tablets/iPeng/iPods

betateilchen

#35
Die Frage wäre in einem neuen Thread besser aufgehoben gewesen.
Und das vorzugsweise im richtigen Unterforum zu JsonMod.

Und um Dir weiterhelfen zu können, könnte ein ausführliches Log beim Verbindungsversuch hilfreich sein.
Ist da wirklich ein Leerzeichen bei der Angabe des api_keys?
Funktioniert der direkte Aufruf Deiner URL im Browser?
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

dadoc

Zitat von: betateilchen am 13 Juli 2023, 16:12:34Die Frage wäre in einem neuen Thread besser aufgehoben gewesen.
Und das vorzugsweise im richtigen Unterforum zu JsonMod.
Stimmt, sorry. Dachte nur, dass sei evtl. dasselbe Problem wie das des TS.
ZitatIst da wirklich ein Leerzeichen bei der Angabe des api_keys?
Ja. Ich hatte es nicht bemerkt, da die Zeile im WebUI genau da umbricht ... War ein neuer API-Code, den ich vor ein paar Tagen angefordert hatte, als es nicht mehr funktionierte.
ZitatFunktioniert der direkte Aufruf Deiner URL im Browser?
Ja, und zwar sowohl ohne als auch mit initialem Leerzeichen im API Code (?api_key=%20eyJhbGciOiJI). Im JSONMOD Modul scheint es aber nur ohne das Leerzeichen zu funktionieren, wie ich gerade ausprobiert habe. Insofern ist jetzt wieder alles so wie es soll - Danke für den Hinweis!
[/quote]
Standort 1: FS20 mit CUL und FHEM auf Raspi. HM-Komponenten (Heizung, Rollladen, Schalter). HM IP über Raspimatic (testweise)
Standort 2: Homematic (Wired) über CCU2 und PocketHome HD
3 x Raspi3 mit piCorePlayer/Kodi für Multiroom Audio (+ Tablets/iPeng/iPods