ESPHome Native API server library.
Espex implements the ESPHome Native API protocol over TCP, letting an Elixir application expose itself as an ESPHome device to clients such as Home Assistant. The wire protocol, connection lifecycle, and optional Noise-encrypted transport all live here; hardware is plugged in through behaviours.
Documentation map
- Architecture — supervision tree, the
connection/dispatch split, wire protocol, encryption, and the
push_state/2broadcast path - Entity types — per-type cookbook for the common ESPHome entities (Switch, BinarySensor, Sensor, Button, Light, Cover, Climate) with proto structs and example snippets
Espex.SerialProxy,Espex.ZWaveProxy,Espex.InfraredProxy,Espex.EntityProvider,Espex.Mdns— the five behaviours, each with callback reference and a complete example adapter
Quick start
Start under your own supervision tree:
children = [
{Espex,
device_config: [name: "my-device", friendly_name: "My Device"],
serial_proxy: MyApp.MySerialAdapter,
zwave_proxy: MyApp.MyZWaveAdapter,
infrared_proxy: MyApp.MyInfraredAdapter,
entity_provider: MyApp.MyEntities}
]
Supervisor.start_link(children, strategy: :one_for_one)Any adapter key you omit disables that feature. For encrypted
transport, set :psk on :device_config:
device_config: [
name: "my-device",
psk: "foIclFXDcBlfzi9oQNegJz/uRG/sgdIc956pX+GrC+A="
]For the full start option list see Espex.Supervisor.
Pushing state
Call push_state/2 from anywhere in your application to broadcast
an entity state update to every currently-connected client:
Espex.push_state(%Espex.Proto.SensorStateResponse{
key: 1003,
state: 21.3,
missing_state: false
})
Summary
Functions
child_spec/1 — makes {Espex, opts} usable as a child spec.
Return the running server's %DeviceConfig{}. Accepts an optional
server name for non-default supervisor setups.
Broadcast an entity-state struct to every currently-connected client.
Start the full Espex supervision tree with the given options.
Functions
@spec child_spec(keyword()) :: Supervisor.child_spec()
child_spec/1 — makes {Espex, opts} usable as a child spec.
@spec device_config(GenServer.server()) :: Espex.DeviceConfig.t()
Return the running server's %DeviceConfig{}. Accepts an optional
server name for non-default supervisor setups.
Broadcast an entity-state struct to every currently-connected client.
Pass any %Espex.Proto.*StateResponse{} (e.g.
%Espex.Proto.SensorStateResponse{key: k, state: 21.3}). Clients that
subscribed via SubscribeStatesRequest will receive the frame over
their socket.
server_name defaults to Espex.Server — pass your custom name if
you started the supervisor with :server_name.
@spec start_link(keyword()) :: Supervisor.on_start()
Start the full Espex supervision tree with the given options.