#How to use websockets?

1 messages · Page 1 of 1 (latest)

warm edge
#

@shy monolith ` from websocket import create_connection
import json
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhNjY4OTk1ZGQ5Mzg0YWRiOGEwZTk1OGUxZmM0YWJlZiIsImlhdCI6MTcwNTI0MjcyOSwiZXhwIjoyMDIwNjAyNzI5fQ.VKxml-fWpsuBZExIHViE2WEg1ZqxDcbNFFKWJIyflhc"
ha_server_host = "192.168.1.16"
ha_server_port = 8123

connect to websocket

ws = create_connection('ws://{}:{}/api/websocket'.format(ha_server_host, ha_server_port))

on connection, server should respond with '{"type":"auth_required","ha_version":"2069.69.69"}'

print(json.loads(ws.recv()))
ws = create_connection('ws://{}:{}/api/websocket'.format(ha_server_host, ha_server_port))

Try send valid login if token is ok, client shall recieve '{"type":"auth_ok","ha_version":"2024.1.2"}'

ws.send('''{"type":"auth","access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhNjY4OTk1ZGQ5Mzg0YWRiOGEwZTk1OGUxZmM0YWJlZiIsImlhdCI6MTcwNTI0MjcyOSwiZXhwIjoyMDIwNjAyNzI5fQ.VKxml-fWpsuBZExIHViE2WEg1ZqxDcbNFFKWJIyflhc"}''')
print(json.loads(ws.recv()))

if token is invalid, auth will return: {"type":"auth_invalid","message":"Invalid access token or password"}

NOTE: this will generate and invalid login attempt massage in HA web interface.

Received '' <-- server returns empty request for some reason, does not allow auth requst, connection must be closed and reopened

websocket._exceptions.WebSocketConnectionClosedException: Connection to remote host was lost.

ws.send(json.dumps({'id': 1,'type': 'subscribe_entities'}))
print(json.dumps(json.loads(ws.recv()), indent=2))
print(json.dumps(json.loads(ws.recv()), indent=2))
ws.send(json.dumps({'id': 2,'type': 'subscribe_entities', 'entity_ids': ['weather.forecast_haserver', 'sun.sun']}))
print(json.dumps(json.loads(ws.recv()),indent=2))
print(json.dumps(json.loads(ws.recv()),indent=2))
print(json.dumps(json.loads(ws.recv()),indent=2))
print(json.dumps(json.loads(ws.recv()),indent=2))
exit(0)`

#

Hey, so ran into the same non-existent documentation issue for the websocket, so far managed to figure out how to get a list of entities, take a look at the above.

#

FYI found that you can reverse engineer a lot of stuff using the browser devtools->network, when you open the webinterface of HA. Yet to dig in the code to find out how this works.

shy monolith
#

I am working on a personal project to ingest and index all my IoT device / entity data into MongoDB for further analysis and play. The project (in its infancy) is at https://github.com/brulejr/iot-tracker (Sorry no doco as of yet). HA, custom hardware, and other webservices are my ingest sources.

I have HA entity change events ingesting / indexing through websockets. But I could not figure a way to get device data via websocket. As such I created a template in HA and use the REST /api/template endpoint to get the data via REST. The template is as follows:

{% macro get_device_list() %}
{% set devices = states | map(attribute='entity_id') | map('device_id') | unique | reject('eq',None) | list %}
{%- set ns = namespace(devices = []) %}
{%- for device in devices %}
  {%- set entities = device_entities(device) | list %}
  {%- if entities %}
    {%- set ns.devices = ns.devices +  [ {"device_id": device, "area_id": device_attr(device, "area_id"), "manufacturer": device_attr(device, "manufacturer"), "device_model": device_attr(device, "name"), "device_name": device_attr(device, "name_by_user"), "entities": entities} ] %}
  {%- endif %}
{%- endfor %}
{{ ns.devices | to_json }}
{% endmacro %}

This works, but I hear word that the REST API is to be deprecated.

Sorry that I don't have Javascript or Python code for this, as I am a Java-at-work, Kotlin-at-home weenie.

#

BTW, this is a sample event of what I had gotten from the subscribe_events call:

{
    "event_type": "state_changed",
    "data": {
        "entity_id": "sensor.temperature_den_1_wifi_signal",
        "old_state": {
            "entity_id": "sensor.temperature_den_1_wifi_signal",
            "state": "-75",
            "attributes": {
                "state_class": "measurement",
                "unit_of_measurement": "dBm",
                "device_class": "signal_strength",
                "friendly_name": "temperature-den-1_wifi_signal"
            },
            "last_changed": "2024-01-04T13:08:55.865997+00:00",
            "last_updated": "2024-01-04T13:08:55.865997+00:00",
            "context": {
                "id": "01HKA9EMDSVTYZGYE3JSYRGXWZ",
                "parent_id": null,
                "user_id": null
            }
        },
        "new_state": {
            "entity_id": "sensor.temperature_den_1_wifi_signal",
            "state": "-76",
            "attributes": {
                "state_class": "measurement",
                "unit_of_measurement": "dBm",
                "device_class": "signal_strength",
                "friendly_name": "temperature-den-1_wifi_signal"
            },
            "last_changed": "2024-01-04T13:10:55.873788+00:00",
            "last_updated": "2024-01-04T13:10:55.873788+00:00",
            "context": {
                "id": "01HKA9J9M17D10YC9VD22DJGCF",
                "parent_id": null,
                "user_id": null
            }
        }
    },
    "origin": "LOCAL",
    "time_fired": "2024-01-04T13:10:55.873788+00:00",
    "context": {
        "id": "01HKA9J9M17D10YC9VD22DJGCF",
        "parent_id": null,
        "user_id": null
    }
}