Hassock.Cache (hassock v0.2.0)

Copy Markdown View Source

Optional ETS-backed cache of all Home Assistant entity states.

Subscribes the underlying Hassock.Connection to every entity using HA's subscribe_entities command. The first event payload contains the full initial snapshot; later payloads ship compressed a/c/r deltas including newly created and deleted entities. ETS is kept in sync.

Ownership

Starting a cache for a connection transfers ownership of that connection to the cache (Hassock.Connection.controlling_process/2). The transfer is performed inside start_link/1 itself — so the process that calls start_link/1 must currently own the connection.

The same caller becomes the cache's own controlling process and receives:

  • {:hassock_cache, cache, :ready} — once, after the initial snapshot loads
  • {:hassock_cache, cache, {:changes, %{added: _, changed: _, removed: _}}} — after each delta event
  • {:hassock_cache, cache, :disconnected} — on socket loss (ETS retained)

Use controlling_process/2 to hand cache events to a different pid. To override the initial controller (e.g. when starting under a supervisor), pass :controlling_pid in the options.

Read API (get/2, get_all/1, get_domain/2) reads ETS directly with no GenServer roundtrip.

Requires Home Assistant >= 2022.4 (when subscribe_entities was added).

Summary

Functions

Returns a specification to start this module under a supervisor.

Transfer cache ownership. Only the current controller may transfer.

Look up an entity by id. Returns nil if not cached.

All cached entities.

All cached entities whose entity_id starts with "<domain>.".

Start a state cache wired to a Connection.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

controlling_process(cache, new_pid)

@spec controlling_process(GenServer.server(), pid()) ::
  :ok | {:error, :not_owner | :not_alive}

Transfer cache ownership. Only the current controller may transfer.

get(cache, entity_id)

@spec get(GenServer.server(), String.t()) :: Hassock.EntityState.t() | nil

Look up an entity by id. Returns nil if not cached.

get_all(cache)

@spec get_all(GenServer.server()) :: [Hassock.EntityState.t()]

All cached entities.

get_domain(cache, domain)

@spec get_domain(GenServer.server(), String.t()) :: [Hassock.EntityState.t()]

All cached entities whose entity_id starts with "<domain>.".

start_link(opts)

@spec start_link(keyword()) :: GenServer.on_start()

Start a state cache wired to a Connection.

Options:

  • :connection — pid or registered name of a Hassock.Connection (required)
  • :controlling_pid — pid that should receive cache events (default: caller)
  • :name — register the cache under this name (optional)
  • :table_name — explicit ETS table name (optional)

The caller must currently own the connection. Ownership is transferred to the new cache as part of start_link/1.