View Source Grizzly (grizzly v4.0.0)

Send commands to Z-Wave devices

Grizzly provides the send_command function as the way to send a command to Z-Wave devices.

The send_command function takes the node id that you are trying to send a command to, the command name, and optionally command arguments and command options.

A basic command that has no options or arguments looks like this:

Grizzly.send_command(node_id, :switch_binary_get)

A command with command arguments:

Grizzly.send_command(node_id, :switch_binary_set, value: :off)

Also, a command can have options.

Grizzly.send_command(node_id, :switch_binary_get, [], timeout: 10_000, retries: 5)

Some possible return values from send_command are:

  1. {:ok, Grizzly.Report.t()} - the command was sent and the Z-Wave device responded with a report. See Grizzly.Report for more information.
  2. {:error, :including} - current the Z-Wave controller is adding or removing a device and commands cannot be processed right now
  3. {:error, :firmware_updating} - current the Z-Wave controller is updating firmware and commands cannot be processed right now
  4. {:error, reason} - there was some other reason for an error, two common ones are: :nack_response

For a more detailed explanation of the responses from a send_command call see the typedoc for Grizzly.send_command_response().

Events from Z-Wave

Events generating from a Z-Wave device, for example a motion detected event, can be handled via the Grizzly.subscribe_command/1 and Grizzly.subscribe_commands/1 functions. This will allow you to subscribe to specific commands. When the command is received from the Z-Wave network it will placed in a Grizzly.Report and set to the subscribing process. The node that generated the report can be accessed with the :node_id field in the report.

iex> Grizzly.subscribe_command(:battery_report)

# sometime latter

iex> flush
{:grizzly, :event, %Grizzly.Report{command: %Grizzly.ZWave.Command{name: :battery_report}}}

Link to this section Summary

Types

A custom handler for the command.

The response from sending a Z-Wave command

Functions

List the command for a particular command class

Guard for checking if device is a virtual device or not

List the support commands

Send a raw binary to the Z-Wave node

Send a command to the node via the node id or to Z/IP Gateway

Subscribe to a command event from a Z-Wave device

Subscribe to many events from a Z-Wave device

Unsubscribe to an event

Check to if the device id is a virtual device or a regular Z-Wave devices

Link to this section Types

@type command() :: atom()
@type command_opt() ::
  {:timeout, non_neg_integer()}
  | {:retries, non_neg_integer()}
  | {:handler, handler()}
  | {:transmission_stats, boolean()}
@type handler() :: module() | {module(), args :: any()}

A custom handler for the command.

See Grizzly.CommandHandler behaviour for more documentation.

@type node_id() :: non_neg_integer()
Link to this type

send_command_response()

View Source
@type send_command_response() ::
  {:ok, Grizzly.Report.t()}
  | {:error,
     :including | :updating_firmware | :nack_response | :queue_full | any()}

The response from sending a Z-Wave command

When everything is okay the response will be {:ok, Grizzly.Report{}}. For documentation about a report see Grizzly.Report module.

When there are errors the response will be in the pattern of {:error, reason}.

Three reasons that Grizzly supports for all commands are :nack_response, :update_firmware, and :including.

In you receive the reason for the error to be :including that means the controller is in an inclusion state and your command will be dropped if we tried to send it. So we won't allow sending a Z-Wave command during an inclusion. It's best to wait and try again once your application is done trying to include.

nack-response

Nack response

A :nack_response normally means that the Z-Wave node that you were trying to send a command to is unreachable and did not receive your command at all. This could mean that the Z-Wave network is overloaded and you should reissue the command, the device is too far from the controller, or the device is no longer part of the Z-Wave network.

Grizzly by default will try a command 3 times before sending returning a :nack_response. This is configurable via the :retries command option in the Grizzly.send_command/4 function. This is useful if you are going to have a known spike in Z-Wave traffic.

queue-full

Queue full

When send commands to a device that sleeps (normally these are sensor type of devices) and the sleeping device is not awake these commands get queued up to be sent once the device wakes up and tells the Z-Wave network that it is awake. However, there is only a limited amount of commands that can be queued at once. When sending a command to a device when the queue is full you will receive the {:error, :queue_full} return from Grizzly.send_command/4. The reason this is an error is because the device will never receive the command that you tried to send.

@type seq_number() :: non_neg_integer()

Link to this section Functions

Link to this function

commands_for_command_class(command_class_name)

View Source
@spec commands_for_command_class(atom()) :: [atom()]

List the command for a particular command class

Link to this macro

is_virtual_device(device_id)

View Source (macro)

Guard for checking if device is a virtual device or not

@spec list_commands() :: [atom()]

List the support commands

Link to this function

send_binary(node_id, binary)

View Source
@spec send_binary(Grizzly.ZWave.node_id(), binary()) ::
  :ok | {:error, :including | :firmware_updating}

Send a raw binary to the Z-Wave node

This function does not block and expects the sending process to handle the lifecycle of the command being sent. This maximizes control but minimizes safety and puts things such as timeouts, retries, and response handling in the hand of the calling process.

When sending the binary ensure the binary is the encoded Grizzly.ZWave.Commands.ZIPPacket.

seq_no = 0x01
{:ok, my_command} = Grizzly.ZWave.Commands.SwitchBinaryGet.new()
{:ok, packet} = Grizzly.ZWave.Commands.ZIPPacket.with_zwave_command(my_command, seq_no)
binary = Grizzly.ZWave.to_binary(packet)

Grizzly.send_binary(node_id, binary)

This is helpful when you need very fine grade control of the Z/IP Packet or if you not expecting a response from a Z-Wave network to handle the back and forth between your application and the Z-Wave network. Also, this can be useful for debugging purposes.

First check if send_command/4 will provide the functionality that is needed before using this function.

After sending a binary packet the calling process will receive messages in the form of:

{:grizzly, :binary_response, binary}
Link to this function

send_command(node_id, command_name, args \\ [], opts \\ [])

View Source
@spec send_command(
  Grizzly.ZWave.node_id() | :gateway | Grizzly.VirtualDevices.id(),
  command(),
  args :: list(),
  [command_opt()]
) :: send_command_response()

Send a command to the node via the node id or to Z/IP Gateway

To talk to your controller directly you can pass :gateway as the node id. This is helpful because your controller might not always be the same node id on any given network. This ensures that not matter node id your controller is you will still be able to query it and make it perform Z-Wave functions. There are many Z-Wave functions a controller do. There are helper functions for these functions in Grizzly.Network and Grizzly.Node.

Link to this function

subscribe_command(command_name)

View Source
@spec subscribe_command(command()) :: :ok

Subscribe to a command event from a Z-Wave device

Link to this function

subscribe_commands(command_names)

View Source
@spec subscribe_commands([command()]) :: :ok

Subscribe to many events from a Z-Wave device

Link to this function

unsubscribe_command(command_name)

View Source
@spec unsubscribe_command(command()) :: :ok

Unsubscribe to an event

Link to this function

virtual_device?(device_id)

View Source
@spec virtual_device?(
  :gateway
  | Grizzly.ZWave.node_id()
  | Grizzly.VirtualDevices.id()
) :: boolean()

Check to if the device id is a virtual device or a regular Z-Wave devices