#How to use websockets?
1 messages · Page 1 of 1 (latest)
@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.
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
}
}