Skip to content

bbangert/espex

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Espex

ESPHome Native API server library for Elixir.

Espex implements the ESPHome Native API protocol over TCP, letting an Elixir application expose itself as an ESPHome device to clients like Home Assistant. The protocol layer and connection lifecycle live here; hardware is plugged in through behaviours.

Status

Early extraction from universal_proxy. Still being tested and iterated on, this is not a final API.

Documentation

Start here once you're ready to go beyond the quickstart below:

  • Architecture guide — supervision tree, the connection/dispatch split, wire protocol, encryption, and how Espex.push_state/2 reaches connected clients.
  • Entity types guide — cookbook for the common ESPHome entities (Switch, BinarySensor, Sensor, Button, Light, Cover, Climate) with proto structs and examples.

Each adapter behaviour's module doc contains a callback reference and a complete example:

  • Espex.SerialProxy
  • Espex.ZWaveProxy
  • Espex.InfraredProxy
  • Espex.EntityProvider
  • Espex.Mdns

Features

  • ESPHome Native API frame encoding/decoding — plaintext and Noise_NNpsk0_25519_ChaChaPoly_SHA256 encrypted transports
  • TCP server with one process per client connection
  • Sub-device support — advertise multiple logical devices under one node
  • Built-in message handling for the Serial Proxy, Z-Wave Proxy, and Infrared Proxy feature sets
  • Server-side state push via Espex.push_state/2 so adapters and EntityProvider implementations can update live values
  • Opt-in mDNS advertising (_esphomelib._tcp) via Espex.Mdns — ships an Espex.Mdns.MdnsLite adapter over the mdns_lite library for the Nerves case, and a behaviour for custom backends
  • Pluggable hardware via behaviours:
    • Espex.SerialProxy
    • Espex.ZWaveProxy
    • Espex.InfraredProxy
    • Espex.EntityProvider

Installation

Add to your mix.exs:

def deps do
  [
    {:espex, "~> 0.1"}
  ]
end

Usage

Plaintext (no encryption):

Espex.start_link(
  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
)

Encrypted (Noise_NNpsk0) — set :psk to either a 32-byte raw binary or a base64-encoded string matching the format used in ESPHome YAML:

Espex.start_link(
  device_config: [
    name: "my-device",
    friendly_name: "My Device",
    psk: "foIclFXDcBlfzi9oQNegJz/uRG/sgdIc956pX+GrC+A="
  ],
  entity_provider: MyApp.MyEntities
)

When a PSK is configured, plaintext clients are rejected with the standard "encryption required" signal so Home Assistant's ESPHome integration prompts the user for the key. Any adapter key you omit disables that feature.

mDNS advertising

Advertise the server as a _esphomelib._tcp service so ESPHome clients auto-discover it. Add :mdns_lite to your application's deps (it's not a runtime dep of espex) and wire the shipped adapter:

# in your mix.exs
{:mdns_lite, "~> 0.8"}

# at start
Espex.start_link(
  device_config: [name: "my-device", ...],
  mdns: Espex.Mdns.MdnsLite
)

For non-Nerves setups (e.g. a host running Avahi), implement your own adapter against the Espex.Mdns behaviour — just advertise(service) and withdraw(service_id):

defmodule MyApp.AvahiAdapter do
  @behaviour Espex.Mdns

  @impl true
  def advertise(service), do: MyApp.Avahi.publish(service)

  @impl true
  def withdraw(id), do: MyApp.Avahi.unpublish(id)
end

Espex.start_link(mdns: MyApp.AvahiAdapter, ...)

Development

mix deps.get
mix compile
mix test
mix credo --strict
mix dialyzer

An interactive demo that starts a server advertising a switch, button and sensor and walks you through an HA connection:

mix run test/manual/live_demo.exs              # plaintext
ESPEX_ENCRYPT=1 mix run test/manual/live_demo.exs  # Noise-encrypted

Roadmap

  • Client-side library (connect to ESPHome devices instead of being one)

License

MIT — see LICENSE.

About

ESPHome API for Elixir devices

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors