# API 1.16

espex 0.10.0 advertises API 1.16 and later. This page covers what 1.16
added.

## What's new

API 1.16 makes the device acknowledge proxy requests that used to go
unanswered, so a client can tell success from failure:

* `ZWaveProxyRequestResponse` after a Z-Wave `SUBSCRIBE` or
  `UNSUBSCRIBE`.
* `SerialProxyRequestResponse` after a serial `CONFIGURE` and
  `SET_MODEM_PINS`, alongside the existing `SUBSCRIBE`,
  `UNSUBSCRIBE` and `FLUSH` answers.
* A `status` on `SerialProxyGetModemPinsResponse`.

## What espex implements

### Z-Wave proxy

| Request | Status | Comes from |
|---------|--------|------------|
| SUBSCRIBE | `OK` | `c:Espex.ZWaveProxy.subscribe/1` returning `{:ok, home_id}` |
| SUBSCRIBE | `IN_USE` | `{:error, :in_use}`: another client holds the controller |
| SUBSCRIBE | `NOT_SUPPORTED` | any other error, or no `:zwave_proxy` adapter |
| UNSUBSCRIBE | `OK` | always (idempotent) |

The `SUBSCRIBE` acknowledgement goes out before the initial
`HOME_ID_CHANGE`, so a client waiting on the acknowledgement sees it
first.

### Serial proxy

Every serial request except `WRITE` is answered. An unknown instance is
`INVALID_ARGUMENT`. The full table is under "Acknowledgements" in
`Espex.SerialProxy`; in short:

| Request | Status comes from |
|---------|-------------------|
| CONFIGURE | `c:Espex.SerialProxy.open/3`: `OK`, or `ERROR` with the reason |
| SET_MODEM_PINS | `c:Espex.SerialProxy.set_modem_pins/3`; `NOT_SUPPORTED` when it is not exported or returns `{:error, :not_supported}` |
| GET_MODEM_PINS | `c:Espex.SerialProxy.get_modem_pins/1`, the same way |

A port opened lazily, by a request that arrives before any `CONFIGURE`,
is not acknowledged on its own; only the request that opened it is.

## Usage

Return the documented values from your adapters. For example, a Z-Wave
adapter that lets one client drive the controller:

    @impl Espex.ZWaveProxy
    def subscribe(pid) do
      case MyApp.ZWave.claim(pid) do
        :ok -> {:ok, MyApp.ZWave.home_id_bytes()}
        {:error, :taken} -> {:error, :in_use}
      end
    end

A serial adapter without modem lines simply leaves out
`set_modem_pins/3` and `get_modem_pins/1`; espex answers
`NOT_SUPPORTED` for it.

## Upgrade notes

* `c:Espex.ZWaveProxy.subscribe/1` returns `{:ok, home_id}` or
  `{:error, reason}`; `{:error, :in_use}` is the one error a client
  shows as "in use".
* `{:error, :not_supported}` from the serial modem-pin callbacks is a
  status, not a failure: it is acknowledged `NOT_SUPPORTED`, not
  `ERROR`.
