Hassock.Connection (hassock v0.2.0)

Copy Markdown View Source

WebSocket client for Home Assistant.

The process that calls start_link/1 becomes the controlling process and receives async messages of the shape {:hassock, conn, payload}:

  • {:hassock, conn, :connected} — once, after auth_ok
  • {:hassock, conn, {:event, payload}} — for each inbound HA event
  • {:hassock, conn, {:disconnected, reason}} — on socket loss
  • {:hassock, conn, {:auth_failed, reason}} — on auth_invalid

Event payload variants:

  • {:state_changed, new_state, old_state} — from subscribe_events("state_changed")
  • {:entities, %{added: _, changed: _, removed: _}} — from subscribe_entities/2
  • {:other, event_type, raw_event} — from any other subscribe_events/2 type

Use controlling_process/2 to transfer ownership to a different pid.

This module performs the auth handshake and nothing else automatically. It does not subscribe to anything on its own — callers drive subscriptions explicitly via subscribe_entities/2, subscribe_events/2, etc.

Summary

Functions

Call a Home Assistant service and wait for the result.

True if authenticated and the underlying socket is connected.

Transfer the controlling process. Only the current controller may transfer ownership.

Fetch all available service domains and their services.

Fetch a one-shot snapshot of all entity states.

Open a Home Assistant WebSocket connection.

Subscribe to entity state updates. Pass nil to subscribe to all entities, or a list of entity_ids to scope. Strictly preferred over subscribe_events("state_changed").

Subscribe to a non-entity HA event type (e.g. "automation_triggered"). Don't use this with "state_changed" — use subscribe_entities/2 instead.

Functions

call_service(conn, call)

@spec call_service(pid() | atom(), Hassock.ServiceCall.t()) ::
  {:ok, term()} | {:error, term()}

Call a Home Assistant service and wait for the result.

connected?(conn)

@spec connected?(pid() | atom()) :: boolean()

True if authenticated and the underlying socket is connected.

controlling_process(conn, new_pid)

@spec controlling_process(pid() | atom(), pid()) ::
  :ok | {:error, :not_owner | :not_alive}

Transfer the controlling process. Only the current controller may transfer ownership.

get_services(conn)

@spec get_services(pid() | atom()) ::
  {:ok, %{required(String.t()) => [String.t()]}} | {:error, term()}

Fetch all available service domains and their services.

get_states(conn)

@spec get_states(pid() | atom()) ::
  {:ok, [Hassock.EntityState.t()]} | {:error, term()}

Fetch a one-shot snapshot of all entity states.

start_link(opts)

@spec start_link(keyword()) :: {:ok, pid()} | {:error, term()}

Open a Home Assistant WebSocket connection.

Options:

  • :config — %Hassock.Config{} (required)
  • :name — register the process under this name (optional)

The calling process becomes the controlling process. If start_link/1 returns {:ok, conn}, the controller will receive a {:hassock, ^conn, :connected} message once authentication completes.

subscribe_entities(conn, entity_ids \\ nil)

@spec subscribe_entities(pid() | atom(), [String.t()] | nil) ::
  {:ok, integer()} | {:error, term()}

Subscribe to entity state updates. Pass nil to subscribe to all entities, or a list of entity_ids to scope. Strictly preferred over subscribe_events("state_changed").

Returns {:ok, subscription_id} on success.

subscribe_events(conn, event_type)

@spec subscribe_events(pid() | atom(), String.t()) ::
  {:ok, integer()} | {:error, term()}

Subscribe to a non-entity HA event type (e.g. "automation_triggered"). Don't use this with "state_changed" — use subscribe_entities/2 instead.

unsubscribe_events(conn, subscription_id)

@spec unsubscribe_events(pid() | atom(), integer()) :: :ok | {:error, term()}

Cancel a subscription returned by subscribe_entities/2 or subscribe_events/2.