My goal is to set up a websocket connection in order to listen on some or all events. Most of my home automation is home-grown, and moving events from HA to the rest of my system would be very useful.
I want to do this from the linux command line – so, using tools available at the shell prompt. So the provided javascript library isn’t much use to me.
Unfortunately, the WebSockets API page of the documentation doesn’t go into the same “required headers” detail that is given on the REST API page. So I can’t be sure I’m doing this right.
I’ve tried a variety of tools, and still can’t make a basic WebSockets connection. No matter what I try, the data I receive back is an HTML page which renders a splash image containing the HA logo. What I am expecting is the server’s “auth_required” message.
Here’s an example of what I’ve tried, using websocat. In this case, I’m using it in a mode where it explicitly calls on socat for the data transfer, which lets us see the exact data being tranferred to and from the server. (I don’t know this tool well, but it appears to be the most capable. And conveniently, this incantation is one of the examples provided.)
#!/bin/bash
wshost=192.168.113.50
port=8123
token="eyJhbGci ... etc...
websocat - \
--header "Authorization: Bearer $token" \
--text \
ws-c:sh-c:"socat -v -x - tcp:$wshost:$port" \
--ws-c-uri ws://$wshost
When I run this, the transmitted headers appear correct, but the received data is for a HA splash page:
> 2023/01/04 14:36:15.453561 length=360 from=0 to=359
47 45 54 20 2f 20 48 54 54 50 2f 31 2e 31 0d 0a GET / HTTP/1.1..
41 75 74 68 6f 72 69 7a 61 74 69 6f 6e 3a 20 42 Authorization: B
65 61 72 65 72 20 65 79 4a 68 62 47 63 69 4f 69 earer eyJhbGciOi
... etc .....................................................
63 50 6c 72 38 72 79 6e 48 30 32 5a 43 49 48 68 cPlr8rynH02ZCIHh
78 42 78 6b 72 7a 77 42 51 4b 54 71 55 0d 0a xBxkrzwBQKTqU..
48 6f 73 74 3a 20 31 39 32 2e 31 36 38 2e 31 31 Host: 192.168.11
33 2e 35 30 0d 0a 3.50..
43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 55 70 67 72 Connection: Upgr
61 64 65 0d 0a ade..
55 70 67 72 61 64 65 3a 20 77 65 62 73 6f 63 6b Upgrade: websock
65 74 0d 0a et..
53 65 63 2d 57 65 62 53 6f 63 6b 65 74 2d 56 65 Sec-WebSocket-Ve
72 73 69 6f 6e 3a 20 31 33 0d 0a rsion: 13..
53 65 63 2d 57 65 62 53 6f 63 6b 65 74 2d 4b 65 Sec-WebSocket-Ke
79 3a 20 74 33 64 34 66 34 61 38 4c 37 74 6d 30 y: t3d4f4a8L7tm0
6d 47 39 70 44 43 6d 4e 77 3d 3d 0d 0a mG9pDCmNw==..
0d 0a ..
--
< 2023/01/04 14:36:15.464491 length=8192 from=0 to=8191
48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d HTTP/1.1 200 OK.
0a .
43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 74 65 Content-Type: te
78 74 2f 68 74 6d 6c 3b 20 63 68 61 72 73 65 74 xt/html; charset
3d 75 74 66 2d 38 0d 0a =utf-8..
43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 Content-Length:
39 32 39 34 0d 0a 9294..
44 61 74 65 3a 20 57 65 64 2c 20 30 34 20 4a 61 Date: Wed, 04 Ja
6e 20 32 30 32 33 20 31 39 3a 33 36 3a 31 35 20 n 2023 19:36:15
47 4d 54 0d 0a GMT..
53 65 72 76 65 72 3a 20 50 79 74 68 6f 6e 2f 33 Server: Python/3
2e 31 30 20 61 69 6f 68 74 74 70 2f 33 2e 38 2e .10 aiohttp/3.8.
31 0d 0a 1..
0d 0a ..
3c 21 44 4f 43 54 59 50 45 20 68 74 6d 6c 3e 3c <!DOCTYPE html><
68 74 6d 6c 3e 3c 68 65 61 64 3e 3c 6c 69 6e 6b html><head><link
20 72 65 6c 3d 22 6d 6f 64 75 6c 65 70 72 65 6c rel="moduleprel
6f 61 64 22 20 68 72 65 66 3d 22 2f 66 72 6f 6e oad" href="/fron
74 65 6e 64 5f 6c 61 74 65 73 74 2f 63 6f 72 65 tend_latest/core
2e 64 64 37 37 32 65 34 31 2e 6a 73 22 20 63 72 .dd772e41.js" cr
6f 73 73 6f 72 69 67 69 6e 3d 22 75 73 65 2d 63 ossorigin="use-c
72 65 64 65 6e 74 69 61 6c 73 22 3e 3c 6c 69 6e redentials"><lin
6b 20 72 65 6c 3d 22 6d 6f 64 75 6c 65 70 72 65 k rel="modulepre
6c 6f 61 64 22 20 68 72 65 66 3d 22 2f 66 72 6f load" href="/fro
... and so on ...
Questions:
- Has anyone else done this?
- Is the protocol exchange necessary for starting WebSockets on HA documented anywhere? It’s the only piece missing from the WebSockets API page.
- Does websockets in HA need to be enabled, somehow, in order to work? As far as I understand, it should be “on” by default. Could I have inadvertently disabled it when I first configured HA, out of ignorance?
Many thanks in advance for your help. I’m happy to clarify in any way.
Oh – I’m running Home Assistant 2022.12.9, Supervisor 2022.12.1, Operating System 9.4, Frontend 20221213.1 - latest