# `Grizzly.ZWave.Command`
[🔗](https://github.com/smartrent/grizzly/blob/v9.1.4/lib/grizzly/zwave/command.ex#L1)

Data struct and behaviour for working with Z-Wave commands

# `params`

```elixir
@type params() :: Keyword.t()
```

Command-specific payload parameters.

# `t`

```elixir
@type t() :: %Grizzly.ZWave.Command{
  command_byte: byte() | nil,
  command_class: atom(),
  name: atom(),
  params: params()
}
```

Command struct

* `:name` - the name of the command
* `:command_class` - the command class module for the command
* `:command_byte` - the byte representation of the command
* `:params` - the parameters for the command as outlined by the Z-Wave
  specification
* `:spec` - the command spec as defined in Grizzly.ZWave.Commands

# `decode_params`

```elixir
@callback decode_params(Grizzly.ZWave.CommandSpec.t(), binary()) ::
  {:ok, keyword()} | {:error, Grizzly.ZWave.DecodeError.t()}
```

Encode the command parameters

# `encode_params`

```elixir
@callback encode_params(Grizzly.ZWave.CommandSpec.t(), t()) :: binary()
```

Encode the command parameters

# `report_matches_get?`
*optional* 

```elixir
@callback report_matches_get?(get :: t(), report :: t()) :: boolean()
```

Returns true if the report is a good match for the get command. This is useful
for commands like Version Command Class Get, which can be sent in rapid succession
during a device interview, which can lead to reports getting matched back to the
wrong get.

This is an optional callback. If not implemented, command handlers will assume true.

# `validate_params`
*optional* 

```elixir
@callback validate_params(Grizzly.ZWave.CommandSpec.t(), params :: keyword()) ::
  {:ok, validated_params :: keyword()} | {:error, reason :: any()}
```

Validate the command's parameters.

The callback should return `{:ok, validated_params}` if the parameters are valid,
or `{:error, reason}` if they are not. Implementers may modify the parameters
during validation (e.g., setting defaults).

# `has_param?`

```elixir
@spec has_param?(t(), atom()) :: boolean()
```

Returns true if the param exists in the command's parameter list.

# `new`

```elixir
@spec new(Grizzly.ZWave.CommandSpec.t(), params :: keyword()) ::
  {:ok, t()} | {:error, :unknown_command}
```

Create a command struct from the given spec and parameters.

# `param`

```elixir
@spec param(t(), atom(), term()) :: term() | nil
```

Get the command param value out the params list

# `param!`

```elixir
@spec param!(t(), atom()) :: term() | no_return()
```

Just like `param/3` but will raise if the the param is not in the param list

# `put_param`

```elixir
@spec put_param(t(), atom(), any()) :: t()
```

Put the param value into the params list, updating pervious value if there is
one

# `to_binary`

```elixir
@spec to_binary(t()) :: binary()
```

Encode the `Command.t()` into it's binary representation

# `validate_params`

Validate a command's parameters according to the command spec.

---

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