Websocket Client - Cookies & Binary

Hi zusammen,

ich möchte gerne auf eine existierende WebSocket API zugreifen und dort Daten empfangen & senden.
Der Ablauf den ich implementieren möchte ist:

  1. REST API Aufruf (POST) zum login; liefert ein token via Cookie header
  2. WebSocket Verbindung mit dem empfangenen Cookie im Header aufbauen
  3. Binary Nachrichten empfangen & senden

Der WebSocket Client sieht ja erstmal gut aus, aber ich sehe zwei Probleme:

  1. Die API die ich anbinden möchte verwendet Cookies für die Authentifizierung; WebSocket Client akzeptiert aber nur eine URL - sehe ich das richtig dass man hier keine Cookies rein kriegt?
  2. Der WebSocket Client unterstützt anscheinend nur Datenpakete vom Typ „Simple“; ich kann beim senden also nicht zwischen binary & text unterscheiden? (Ob binary zumindest vernünftig empfangen wird habe ich noch nicht probiert)

Übersehe ich hier etwas oder müsste ich tatsächlich einen anderen WebSocket Client verwenden?
IPSNetwork hat anscheinend binary support, aber leider auch keinen Cookie Parameter

Wurde von mir auch schon ewig (IPS 4.x/5.0 glaub ich) nicht mehr gepflegt.
Und da wo der bisher wirklich aktiv genutzt wurde, gab es erst den Verbindungsaufbau und dann eine Authentifizierung.
Michael

Um welche API geht es denn? Aktuell kann man keine benutzerdefinierten Header mitgeben, da wir das konzeptionell im SSE erlauben wäre eine Erweiterung beim WebSocket jetzt nicht ausgeschlossen.

paresy

Es geht um die Unifi Protect Realtime Updates API.

Beispiel/Doku z.B. hier: homebridge-unifi-protect/ProtectAPI.md at master · hjdhjd/homebridge-unifi-protect · GitHub

Benutzerdefinierte Header wäre natürlich Klasse, das würde das Problem lösen.

Und senden/empfangen von Text & Binary Paketen geht schon, oder würde ggf auch noch hinzugefügt werden können? Da das ja auf WebSocket Protokoll unterschiedliche OpCode sind müsste man dem Socket ja irgendwie sagen können was er schicken soll.

Sorry for english, but my deutsch ist nicht gut, leider…

If we could get headers in WS, would that make it possible to access Tibber API, as well? Tibber Developer I have to send an authorization token to the server through the Authorization header and must be included on every call. Sorry If I’m erroneously is highjacking your thread because of my meagre skills in programming, and it’s about something else…

Yes, custom headers as suggested by paresy would also allow to pass the Authorization header as described in that doc.

I’m also using Tibber by the way… did not have time yet to check their API, but good to know, now I have two reasons for this request :smiley:

I use tibber in Norway, as I understand it it’s a bit different in Germany. Right now i’m searching for a way to get the current consumption and det accumulated consumption for the last hour, because of the governments plan to charge extra for housholds that exceed 5kWh in any given hour in a month. The tibber API has all the relevant data, I just don’t understand how to access it and integrate it into tibber. My programming skills is mainly copy paste, and lots of work to try and understand what I’m doing and adjust the pasted parts to suit me… :slight_smile:

Just FYI: I just merged custom header support for the WebSocket Client into IP-Symcon 6.1

paresy

1 „Gefällt mir“

Awesome! Thanks a lot.

Thanks! Just tried it. I get the same error as I got before i could add the header: „closed: code 1002“. As the change didn’t affect the error, is there somthing else I’ve done wrong? Or is there a problem elsewhere?

Andreas

Does the same Header work when you e.g. test it using Postman?

paresy

No. I get the same error there, but then I might be doing something wrong, but i tried different combinations og capitalized/lower case, headers/params etc, but i get the same error „1002 protocol error“.

I tried the python script at the end of the tibber documentation, to see if I was using the token wrong or something, and that worked just nice (long live copy paste!). It might be a workaround, but I’d rather have it directly into IPS.

I just got Feedback from @tharit that it is working for him therefore i think that you need to check the Tokens at your end :slight_smile:

paresy

@cinemarillion I had a look at the tibber api. The documentation is misleading if not wrong… the Authorization header is probably only used for the REST API, whereas WS works differently.

I had a look at a node module (tibber-api/TibberFeed.ts at master · bisand/tibber-api · GitHub) to figure out what you actually need to do to connect from IP-Symcon. Good news is you DO need the custom header functionality, just a different header…

  1. You do NOT need to send the „Authorization“ header
  2. You DO need to send the „Sec-WebSocket-Protocol“ header with a value of „graphql-ws“
  3. At this point the socket does stay open, and you have to start speaking graphql
  4. Start & authorize the connection by sending the „connection_init“ package with your token!
    e.g. {„id“:1,„type“:„connection_init“,„payload“:{„token“:<INSER_TOKEN_HERE>}}
  5. server will respond with {„type“:„connection_ack“}.

Now you just need to figure out what you want to subscribe to & handle the data :slight_smile:

Vielen dank! Thad did it, I now got a stable connection! I came as long as to piont 3, and then my skills ran short… I don’t have quite the skills to put it into a php script. Would it be to much to ask for a suggestion on how such a script would look like? :slight_smile:

Hola, sorry for bringing this topic up again. I wonder how to address the changing cookie and csfr token with the websocket client. Is there a way to write those values from within a script?
I’m using it for motion detection with Unifi Protect and aside from expiring cookies it works just fine.

Thanks!
Alex

Sure. Just have a look at IPS_SetProperty and IPS_ApplyChanges. You can reconfigure any instance by script as you wish.

paresy

Hi paresy, Danke für die Antwort! :smiley:

Meinst Du vielleicht IPS_GetConfiguration();?
Hatte mit SetProperty keinen Erfolg den Header neu zu schreiben.
Was mich jetzt noch wundert ist:

echo IPS_GetProperty(<INSTID_Websocket_Client>, „Open“);
Warning: Eigenschaft Open nicht gefunden in /var/lib/symcon/scripts/30493.ips.php on line 1

Viele Grüße aus Spanien!
Alex

Mit IPS_GetConfiguration bekommst du alle verfügbaren Properties. Diese willst du dann mit IPS_SetProperty einzeln ändern.

paresy

Hast du es hinbekommen binäre Daten zu senden und zu empfangen?

Ich habe da auch gerade ein Problem und vermute es hängt damit zusammen. Wenn ich die Daten per Postman sende, funktioniert es mit binären Daten, von Symcon aus nicht.