The major breaking change to Grizzly when going from v0.12 or earlier to v0.13 is the main API call Grizzly.send_command/4
now returns {:ok, %Grizzly.Report{}}
when the command was successfully sent. A successful command can return 4 primary reports:
:ack_response
:command
:queued
:timeout
This types can be accessed in the Grizzly.Report
's :type
field.
When using send_command/4
the old code would look like:
case Grizzly.send_command(node_id, command, command_args, command_opts) do
:ok -> # do stuff
{:ok, %Grizzly.Command{}} -> # do stuff
{:queued, ref, delay_seconds} -> # do stuff
end
To update the above code:
case Grizzly.send_command(node_id, command, command_args, command_opts) do
{:ok, %Grizzly.Report{status: :complete, type: :ack_response}} -> # do stuff
{:ok, %Grizzly.Report{status: :complete, type: :command}} -> # do stuff
{:ok, %Grizzly.Report{status: :complete, type: :timeout}} -> # do stuff
{:ok, %Grizzly.Report{status: :inflight, type: :queued}} -> # do stuff
end
Notice the queued command's status is considered to still be inflight as it hasn't reached the destination node yet.
A :complete
report means the command finished its lifecylce and no runtime issues with processing the command and the responses to the command.
When you have a :command
type of report you can access the Z-wave command via the :command
field of the report.
If the command is queued and you want to track the life of the queued command the reference to the command is in the :command_ref
field of the report. Also, to know how long the command is projected to delayed you can use the :queued_delay
field of the report, this is in seconds.
For more information about the new report data structure please see the Grizzly.Report
module docs.
Just like the <= v0.12 versions when a command is queued there are ping and a final reports. This was sent to the calling process in this form:
{:grizzly, :queued_command_response, %Grizzly.Command{}}
{:grizzly, :queued_ping, reference, remaining_delay}
To handle the new report based messaging with queued commands you should update to handle:
{:grizzly, :report, %Grizzly.Report{}}
An example of this might look like:
def handle_info({:grizzly, :report, report}, state) do
if report.queued do
handle_queued_response(report, state)
else
handle_unknown_report(report, state)
end
end
def handle_queued_response(report, state) do
case report do
%Report{status: :inflight, type: :queued_ping} ->
# and updated queued delay timer can be found in the
# queued_delay field of the report like: report.queued_delay
%Report{status: :complete, type: :ack_response} ->
# do stuff with the ack response report
%Report{status: :complete, type: :command} ->
# do something with the command that can be found in the
# report's :command field like: report.command
%Report{status: :complete, type: :timeout} ->
# when the device woke up and the controller sent the
# command, for some reason the command timedout.
end
end
The Grizzly inclusion handler behaviour has changed from handle_command/2
to handle_report/2
and the inclusion handler will be sent the report data stucuture.
Unsolicited messages are messages from the Z-Wave network to Grizzly. This might be montion detected report or an unlock report if a lock was manually unlocked. When subscribiing to a command to listen to the old message that was sent use to be:
{:grizzly, :event, %Grizzly.Command{}
This is now
{:grizzly, :report, %Grizzly.Report{}}
Where the Grizzly.Command
data structure can be accessed by the :command
field on the report.
The patterns for handling vairous pushed messages looked like:
# queued command reponse
{:grizzly, :queued_command_response, %Grizzly.Command{}}
# queued ping
{:grizzly, :queued_ping, reference, remaining_delay}
# unsolicited messages
{:grizzly, :event, %Grizzly.Command{}}
# inclusions
{:grizzly, :inclusion, %Grizzly.Command{}}
# firmware updates
{:grizzly, :firmware_update, %Grizzly.Command{}}
They all follow this pattern now:
{:grizzly, :report, %Grizzly.Report{}}
Now that the Grizzly.Report
data structure can provide a lot more context of the Z-Wave communication the handler of these messages can use pattern matching or other means to introspect the report to know how to handle it. This also makes the footprint of Grizzly's API a little smaller, hopefully lowering the learning curve.