# `MAVLink2.Param`
[🔗](https://github.com/isaiahdw/mavlink2/blob/v0.1.0/lib/mavlink2/param.ex#L1)

MAVLink's parameter protocol: read, set and list a component's
parameters.

    MAVLink2.Param.read(link, {1, 1}, "SYSID_THISMAV")
    #=> {:ok, %{name: "SYSID_THISMAV", value: 1, type: :mav_param_type_int32, index: 802, count: 1203}}

The link's dialect must have the messages (`common.xml` does). `target`
is `{sysid, compid}`.

`PARAM_VALUE` carries every value in a float. Autopilots put integers in
it one of two ways, chosen with `:encoding`:

| | |
| --- | --- |
| `:cast` (default) | the integer converted to a float, as ArduPilot does |
| `:bytewise` | the integer's bytes in the float's, as PX4 does (`MAV_PROTOCOL_CAPABILITY_PARAM_ENCODE_BYTEWISE`) |

A `REAL32` value is a float either way. 64-bit types do not fit and
are returned as the float on the wire.

Options:

| | |
| --- | --- |
| `:encoding` | as above |
| `:timeout` | ms to wait for a reply before asking again (default 1000); for `list/3`, the quiet time that ends the stream |
| `:retries` | times to ask again (default 3) |

A parameter is `%{name, value, type, index, count}`, `type` a
`MAV_PARAM_TYPE` entry atom.

# `encoding`

```elixir
@type encoding() :: :cast | :bytewise
```

# `param`

```elixir
@type param() :: %{
  name: String.t(),
  value: number() | :nan | :infinity | :neg_infinity,
  type: atom() | integer(),
  index: non_neg_integer(),
  count: non_neg_integer(),
  component: 0..255
}
```

# `from_wire`

```elixir
@spec from_wire(
  float() | :nan | :infinity | :neg_infinity,
  binary(),
  integer(),
  encoding()
) ::
  number() | :nan | :infinity | :neg_infinity
```

A wire float (and its raw 4 bytes) as the parameter's value, for a
`MAV_PARAM_TYPE` value and an encoding.

# `list`

```elixir
@spec list(GenServer.server(), MAVLink2.target(), keyword()) ::
  {:ok, [param()]} | {:error, term()}
```

Every parameter, in component and index order. With target compid 0
(`MAV_COMP_ID_ALL`), every component of the system that answers is
included, each parameter with its `component`.

After the stream goes quiet, each missing index is asked for on its own.
`{:error, {:missing, [{component, index}]}}` when some never arrive. A
`PARAM_VALUE` whose index is not below its count is not part of the list
(PX4 sends its parameter-set hash at index 32767).

# `read`

```elixir
@spec read(
  GenServer.server(),
  MAVLink2.target(),
  String.t() | non_neg_integer(),
  keyword()
) ::
  {:ok, param()} | {:error, term()}
```

Reads one parameter, by name or by index. A target that answers with
`PARAM_ERROR` (a dialect with it, such as current `common.xml`) ends the
wait with `{:error, {:param_error, error}}`, `error` a `MAV_PARAM_ERROR`
atom such as `:mav_param_error_does_not_exist`.

# `set`

```elixir
@spec set(
  GenServer.server(),
  MAVLink2.target(),
  String.t(),
  number(),
  atom() | integer(),
  keyword()
) :: {:ok, param()} | {:error, term()}
```

Sets a parameter and returns the value the target reports back, which
is what it now holds: compare it with `value` to see whether the target
took it. `type` is a `MAV_PARAM_TYPE` atom or value. `PARAM_ERROR` ends
the wait as for `read/4`.

The protocol has the target answer with `PARAM_VALUE`. For one that does
not, as the MAVLink guide notes of ArduPilot, the value is read back by
name once the retries run out.

# `to_wire`

```elixir
@spec to_wire(number(), integer(), encoding()) ::
  {float(), [{:param_value, binary()}]}
```

A value as the wire float and, for a bytewise integer, the raw bytes to
put in its place.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
