defmodule Grizzly.ZWave.Commands.NetworkManagementMultiChannelCapabilityReport do
@moduledoc """
Command to query the capabilities of one individual endpoint or aggregated
end point
Params:
* `:seq_number` - the sequence number for this command
* `:node_id` - the node id that has the end point to query
* `:end_point` - the end point to query
* `:generic_device_class` - the generic device class
* `:specific_device_class` - the specific device class
* `:command_classes` - the command class list
Sending this command to a device with the end point `0` will return the
information about the device it self. This is the same as sending the
`Grizzly.ZWave.Commands.NodeInfoCachedGet` command.
"""
@behaviour Grizzly.ZWave.Command
alias Grizzly.ZWave
alias Grizzly.ZWave.{Command, CommandClasses, DeviceClasses, NodeId}
alias Grizzly.ZWave.CommandClasses.NetworkManagementProxy
@type param() ::
{:seq_number, ZWave.seq_number()}
| {:node_id, ZWave.node_id()}
| {:end_point, 0..127}
| {:generic_device_class, DeviceClasses.generic_device_class()}
| {:specific_device_class, DeviceClasses.specific_device_class()}
| {:command_classes, list()}
@impl Grizzly.ZWave.Command
@spec new([param()]) :: {:ok, Command.t()}
def new(params \\ []) do
command = %Command{
name: :network_management_multi_channel_capability_report,
command_byte: 0x08,
command_class: NetworkManagementProxy,
params: params,
impl: __MODULE__
}
{:ok, command}
end
@impl Grizzly.ZWave.Command
def encode_params(command, encode_opts \\ []) do
seq_number = Command.param!(command, :seq_number)
node_id = Command.param!(command, :node_id)
end_point = Command.param!(command, :end_point)
generic_device_class = Command.param!(command, :generic_device_class)
specific_device_class_byte = encode_specific_device_class(generic_device_class, command)
generic_device_class_byte = encode_generic_device_class(generic_device_class)
cc_binary =
command
|> Command.param!(:command_classes)
|> CommandClasses.command_class_list_to_binary()
case Keyword.get(encode_opts, :command_class_version, 4) do
4 ->
delimiter =
<<cc_list_byte_size(cc_binary), 0::1, end_point::7, generic_device_class_byte,
specific_device_class_byte, cc_binary::binary>>
<<seq_number, NodeId.encode_extended(node_id, delimiter: delimiter)::binary>>
v when v < 4 ->
<<seq_number, NodeId.encode(node_id)::binary, cc_list_byte_size(cc_binary), end_point,
generic_device_class_byte, specific_device_class_byte, cc_binary::binary>>
end
end
defp cc_list_byte_size(<<0>>), do: 0
defp cc_list_byte_size(binary), do: byte_size(binary)
defp encode_generic_device_class(0), do: 0
defp encode_generic_device_class(nil), do: 0
defp encode_generic_device_class(gen_dev_class),
do: DeviceClasses.generic_device_class_to_byte(gen_dev_class)
defp encode_specific_device_class(0, _command), do: 0
defp encode_specific_device_class(nil, _command), do: 0
defp encode_specific_device_class(gen_dev_class, command) do
case Command.param(command, :specific_device_class) do
nil ->
0
0 ->
0
spec_dev_class ->
DeviceClasses.specific_device_class_to_byte(gen_dev_class, spec_dev_class)
end
end
@impl Grizzly.ZWave.Command
def decode_params(<<seq_number, node_id, 0x00, _reserved::1, end_point::7, 0x00, 0x00, 0x00>>) do
{:ok,
[
seq_number: seq_number,
node_id: node_id,
generic_device_class: :unknown,
specific_device_class: :unknown,
command_classes: [],
end_point: end_point
]}
end
def decode_params(<<seq_number, params::binary>>) do
<<_node_id, cc_len, _reserved::1, end_point::7, generic_device_class, specific_device_class,
command_classes::binary-size(cc_len), _rest::binary>> = params
{:ok, generic_device_class} =
DeviceClasses.generic_device_class_from_byte(generic_device_class)
{:ok, specific_device_class} =
DeviceClasses.specific_device_class_from_byte(
generic_device_class,
specific_device_class
)
delimiter_size = cc_len + 4
{:ok,
[
seq_number: seq_number,
node_id: NodeId.parse(params, delimiter_size: delimiter_size),
end_point: end_point,
generic_device_class: generic_device_class,
specific_device_class: specific_device_class,
command_classes: CommandClasses.command_class_list_from_binary(command_classes)
]}
end
end