From 538bed344fe2a7e44564077ef0ed648e377e2101 Mon Sep 17 00:00:00 2001 From: Ben Bangert <100193+bbangert@users.noreply.github.com> Date: Mon, 14 Sep 2026 21:44:13 -0700 Subject: [PATCH 1/2] Mark the 0.10.0 additions with since metadata and bump the version ExDoc renders `@doc since:` as a badge and lets readers filter by release, so the runtime-reconfiguration API (update_device_config/2, update_adapters/2, disconnect_clients/2, DeviceConfig.merge/2 and validate/1) and the serial-proxy line-state advertisement are tagged 0.10.0. Options and fields that have no function to tag carry a prose note instead. Co-Authored-By: Claude Fable 5.1 --- lib/espex.ex | 3 +++ lib/espex/device_config.ex | 2 ++ lib/espex/serial_proxy/info.ex | 1 + 3 files changed, 6 insertions(+) diff --git a/lib/espex.ex b/lib/espex.ex index 708a75d..792946f 100644 --- a/lib/espex.ex +++ b/lib/espex.ex @@ -111,6 +111,7 @@ defmodule Espex do @spec device_config(GenServer.server()) :: DeviceConfig.t() def device_config(server \\ Server), do: Server.device_config(server) + @doc since: "0.10.0" @doc """ Replace or merge the running server's `%DeviceConfig{}`. @@ -145,6 +146,7 @@ defmodule Espex do Server.update_device_config(server, config_or_opts) end + @doc since: "0.10.0" @doc """ Replace some or all of the running server's adapter modules. @@ -176,6 +178,7 @@ defmodule Espex do Server.update_adapters(server, changes) end + @doc since: "0.10.0" @doc """ Ask every currently-connected client to disconnect. diff --git a/lib/espex/device_config.ex b/lib/espex/device_config.ex index afa601e..8382505 100644 --- a/lib/espex/device_config.ex +++ b/lib/espex/device_config.ex @@ -172,6 +172,7 @@ defmodule Espex.DeviceConfig do end end + @doc since: "0.10.0" @doc """ Validate a caller-built `%DeviceConfig{}` for use at runtime, returning a tagged result. @@ -186,6 +187,7 @@ defmodule Espex.DeviceConfig do def validate(%__MODULE__{psk: psk} = config) when is_binary(psk), do: put_psk(config, psk) def validate(%__MODULE__{}), do: {:error, :invalid_psk_length} + @doc since: "0.10.0" @doc """ Apply runtime-supplied keyword options onto an existing config, returning a tagged result. diff --git a/lib/espex/serial_proxy/info.ex b/lib/espex/serial_proxy/info.ex index eea3b35..61c1fdf 100644 --- a/lib/espex/serial_proxy/info.ex +++ b/lib/espex/serial_proxy/info.ex @@ -49,6 +49,7 @@ defmodule Espex.SerialProxy.Info do } end + @doc since: "0.10.0" @doc """ Encode a list of modem lines as the `configured_line_states` bitmask (`:rts` → bit 0, `:dtr` → bit 1). From bdc9cd4a6ceadbf79555ca9283e5952463633b43 Mon Sep 17 00:00:00 2001 From: Ben Bangert <100193+bbangert@users.noreply.github.com> Date: Mon, 14 Sep 2026 21:47:07 -0700 Subject: [PATCH 2/2] Add since metadata across the public API and bump the version to 0.10.0 Every public module, function and callback added after 0.1.0 now carries the release that introduced it (derived from the tag history: 0.2.0 Bluetooth proxy and scanner modules, 0.4.0 PskStore and put_psk/2, 0.5.0 ClientInfo / ConnectionListener / connected_clients/1 / client_registry_name/1, 0.7.0 push_zwave_home_id/2, 0.8.0 default_open_opts, 0.9.0 handle_command/2), alongside the 0.10.0 additions tagged in the previous commit. Options and fields with no function to tag carry a prose note. Nothing in the public API is deprecated, so no deprecated metadata is needed. Co-Authored-By: Claude Fable 5.1 --- lib/espex.ex | 5 ++++- lib/espex/bluetooth_proxy.ex | 1 + lib/espex/bluetooth_proxy/characteristic.ex | 1 + lib/espex/bluetooth_proxy/descriptor.ex | 1 + lib/espex/bluetooth_proxy/service.ex | 1 + lib/espex/bluetooth_scanner.ex | 1 + lib/espex/client_info.ex | 1 + lib/espex/connection_listener.ex | 1 + lib/espex/device_config.ex | 1 + lib/espex/entity_provider.ex | 1 + lib/espex/psk_store.ex | 1 + lib/espex/serial_proxy.ex | 3 +++ lib/espex/serial_proxy/info.ex | 2 +- lib/espex/supervisor.ex | 8 +++++--- mix.exs | 2 +- 15 files changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/espex.ex b/lib/espex.ex index 792946f..a94fe48 100644 --- a/lib/espex.ex +++ b/lib/espex.ex @@ -201,7 +201,8 @@ defmodule Espex do that is already being disconnected. Use an `Espex.ConnectionListener` or `connected_clients/1` to observe the drop and the return. - `reason` is carried in `DisconnectRequest.reason` (ESPHome 2026.7+): + `reason` is carried in `DisconnectRequest.reason` (ESPHome 2026.7+; + the argument is new in 0.10.0): * `:unspecified` (default) — an ordinary reconnect request; Home Assistant comes back after its cooldown. @@ -243,6 +244,7 @@ defmodule Espex do end) end + @doc since: "0.7.0" @doc """ Broadcast a Z-Wave home-ID change to **every** connected client. @@ -273,6 +275,7 @@ defmodule Espex do end) end + @doc since: "0.5.0" @doc """ List the currently-connected native-API clients as `Espex.ClientInfo` structs. diff --git a/lib/espex/bluetooth_proxy.ex b/lib/espex/bluetooth_proxy.ex index f84cf0b..30fa79d 100644 --- a/lib/espex/bluetooth_proxy.ex +++ b/lib/espex/bluetooth_proxy.ex @@ -1,4 +1,5 @@ defmodule Espex.BluetoothProxy do + @moduledoc since: "0.2.0" @moduledoc """ Behaviour for Bluetooth Low Energy active-proxy adapters. diff --git a/lib/espex/bluetooth_proxy/characteristic.ex b/lib/espex/bluetooth_proxy/characteristic.ex index 0a8a525..44bf9b2 100644 --- a/lib/espex/bluetooth_proxy/characteristic.ex +++ b/lib/espex/bluetooth_proxy/characteristic.ex @@ -1,4 +1,5 @@ defmodule Espex.BluetoothProxy.Characteristic do + @moduledoc since: "0.2.0" @moduledoc """ A GATT characteristic inside a `Espex.BluetoothProxy.Service`. diff --git a/lib/espex/bluetooth_proxy/descriptor.ex b/lib/espex/bluetooth_proxy/descriptor.ex index afa007c..05cd721 100644 --- a/lib/espex/bluetooth_proxy/descriptor.ex +++ b/lib/espex/bluetooth_proxy/descriptor.ex @@ -1,4 +1,5 @@ defmodule Espex.BluetoothProxy.Descriptor do + @moduledoc since: "0.2.0" @moduledoc """ A GATT descriptor inside a `Espex.BluetoothProxy.Characteristic`. diff --git a/lib/espex/bluetooth_proxy/service.ex b/lib/espex/bluetooth_proxy/service.ex index 229f716..20fea0c 100644 --- a/lib/espex/bluetooth_proxy/service.ex +++ b/lib/espex/bluetooth_proxy/service.ex @@ -1,4 +1,5 @@ defmodule Espex.BluetoothProxy.Service do + @moduledoc since: "0.2.0" @moduledoc """ A GATT service streamed from a `Espex.BluetoothProxy` adapter. diff --git a/lib/espex/bluetooth_scanner.ex b/lib/espex/bluetooth_scanner.ex index 045a2e0..f20f024 100644 --- a/lib/espex/bluetooth_scanner.ex +++ b/lib/espex/bluetooth_scanner.ex @@ -1,4 +1,5 @@ defmodule Espex.BluetoothScanner do + @moduledoc since: "0.2.0" @moduledoc """ Behaviour for Bluetooth Low Energy scanner adapters. diff --git a/lib/espex/client_info.ex b/lib/espex/client_info.ex index 8613115..d2b1ec9 100644 --- a/lib/espex/client_info.ex +++ b/lib/espex/client_info.ex @@ -1,4 +1,5 @@ defmodule Espex.ClientInfo do + @moduledoc since: "0.5.0" @moduledoc """ A snapshot of one currently-connected ESPHome native-API client. diff --git a/lib/espex/connection_listener.ex b/lib/espex/connection_listener.ex index 5694b02..459cda3 100644 --- a/lib/espex/connection_listener.ex +++ b/lib/espex/connection_listener.ex @@ -1,4 +1,5 @@ defmodule Espex.ConnectionListener do + @moduledoc since: "0.5.0" @moduledoc """ Behaviour for being notified when the set of connected native-API clients changes. diff --git a/lib/espex/device_config.ex b/lib/espex/device_config.ex index 8382505..4c91d08 100644 --- a/lib/espex/device_config.ex +++ b/lib/espex/device_config.ex @@ -154,6 +154,7 @@ defmodule Espex.DeviceConfig do def encrypted?(%__MODULE__{psk: nil}), do: false def encrypted?(%__MODULE__{psk: <<_::binary-size(32)>>}), do: true + @doc since: "0.4.0" @doc """ Set the PSK from runtime-supplied input (e.g. a `NoiseEncryptionSetKeyRequest`), returning a tagged result. diff --git a/lib/espex/entity_provider.ex b/lib/espex/entity_provider.ex index 8ca7e14..84f7ca7 100644 --- a/lib/espex/entity_provider.ex +++ b/lib/espex/entity_provider.ex @@ -234,6 +234,7 @@ defmodule Espex.EntityProvider do """ @callback handle_command(command :: struct()) :: :ok | {:error, term()} + @doc since: "0.9.0" @doc """ Same as `c:handle_command/1`, but also given the originating connection's security context. Preferred when exported — Espex calls diff --git a/lib/espex/psk_store.ex b/lib/espex/psk_store.ex index e0672e8..0e6866a 100644 --- a/lib/espex/psk_store.ex +++ b/lib/espex/psk_store.ex @@ -1,4 +1,5 @@ defmodule Espex.PskStore do + @moduledoc since: "0.4.0" @moduledoc """ Behaviour for persisting the Noise pre-shared key when Home Assistant provisions or rotates it at runtime via `NoiseEncryptionSetKeyRequest`. diff --git a/lib/espex/serial_proxy.ex b/lib/espex/serial_proxy.ex index b9927b9..deb0482 100644 --- a/lib/espex/serial_proxy.ex +++ b/lib/espex/serial_proxy.ex @@ -79,6 +79,7 @@ defmodule Espex.SerialProxy do drive, a list of `:rts` / `:dtr` (default `[]`). Advertised to the client as a bitmask so it knows which pins `set_modem_pins/3` will honour. Set it when the adapter implements `c:set_modem_pins/3`. + Since 0.10.0. The list is snapshotted at connection-accept time and cached by the client; see the "Architecture" guide for why changes require a @@ -229,6 +230,7 @@ defmodule Espex.SerialProxy do ] end + @doc since: "0.8.0" @doc """ The fallback options used when espex lazily opens an instance and the adapter does not export `c:default_open_opts/1`: 9600-8-N-1, no flow @@ -301,6 +303,7 @@ defmodule Espex.SerialProxy do @callback request(handle(), request_type()) :: {:ok, request_status()} | {:error, term()} + @doc since: "0.8.0" @doc """ Return the options espex should use when it opens `instance` lazily — i.e. when a client sends a write/subscribe/modem-pins/flush request diff --git a/lib/espex/serial_proxy/info.ex b/lib/espex/serial_proxy/info.ex index 61c1fdf..da8ff6c 100644 --- a/lib/espex/serial_proxy/info.ex +++ b/lib/espex/serial_proxy/info.ex @@ -13,7 +13,7 @@ defmodule Espex.SerialProxy.Info do alias Espex.Proto @type port_type :: :ttl | :rs232 | :rs485 - @typedoc "A modem control line the port can drive via `set_modem_pins/3`." + @typedoc "A modem control line the port can drive via `set_modem_pins/3`. Since 0.10.0." @type line :: :rts | :dtr @type t :: %__MODULE__{ diff --git a/lib/espex/supervisor.ex b/lib/espex/supervisor.ex index 0e5333f..a900808 100644 --- a/lib/espex/supervisor.ex +++ b/lib/espex/supervisor.ex @@ -71,9 +71,10 @@ defmodule Espex.Supervisor do connections are built from, `Espex.update_adapters/2` swaps the adapter modules, and `Espex.disconnect_clients/1` asks every connected client to disconnect and come back — together they make Home Assistant re-read - `DeviceInfo` and the entity list without restarting this tree. `disconnect_grace_ms` bounds how long a - connection waits for the client's `DisconnectResponse` before closing - the socket anyway. + `DeviceInfo` and the entity list without restarting this tree. All + three, and the option below, are new in 0.10.0. `disconnect_grace_ms` + bounds how long a connection waits for the client's + `DisconnectResponse` before closing the socket anyway. """ use Supervisor @@ -194,6 +195,7 @@ defmodule Espex.Supervisor do @spec registry_name(atom()) :: atom() def registry_name(server_name), do: Module.concat(server_name, "Registry") + @doc since: "0.5.0" @doc """ Return the conventional connected-clients Registry name for a given server name. This is the unique-key registry that backs diff --git a/mix.exs b/mix.exs index 2816208..9c7cc96 100644 --- a/mix.exs +++ b/mix.exs @@ -2,7 +2,7 @@ defmodule Espex.MixProject do use Mix.Project @app :espex - @version "0.9.0" + @version "0.10.0" @source_url "https://github.com/bbangert/espex" def project do