Packages
grizzly
6.8.1
9.1.4
9.1.2
9.1.1
9.1.0
9.0.0
8.15.3
8.15.2
8.15.1
8.15.0
8.14.0
8.13.0
8.12.0
8.11.3
8.11.2
8.11.1
8.11.0
8.10.0
8.9.0
8.8.1
8.8.0
8.7.1
8.7.0
8.6.12
8.6.11
8.6.10
8.6.9
8.6.8
8.6.7
retired
8.6.6
8.6.5
8.6.4
8.6.3
8.6.2
8.6.1
8.6.0
8.5.3
8.5.2
8.5.1
8.5.0
8.4.0
8.3.0
8.2.3
8.2.2
8.2.1
8.2.0
8.1.0
8.0.1
8.0.0
7.4.3
7.4.2
7.4.1
7.4.0
7.3.0
7.2.0
7.1.4
7.1.3
7.1.2
7.1.1
7.1.0
7.0.4
7.0.3
7.0.2
7.0.1
7.0.0
6.8.8
6.8.7
6.8.6
6.8.5
6.8.4
6.8.3
6.8.2
6.8.1
6.8.0
6.7.1
6.7.0
6.6.1
6.6.0
6.5.1
6.5.0
6.4.0
6.3.0
6.2.0
6.1.1
6.1.0
6.0.1
6.0.0
5.4.1
5.4.0
5.3.0
5.2.8
5.2.7
5.2.6
5.2.5
5.2.4
5.2.3
5.2.2
5.2.1
5.2.0
5.1.2
5.1.1
5.1.0
5.0.2
5.0.1
5.0.0
4.0.1
4.0.0
3.0.0
2.1.0
2.0.0
1.0.1
1.0.0
0.22.7
0.22.6
0.22.5
0.22.4
0.22.3
0.22.2
0.22.1
0.22.0
0.21.1
0.21.0
0.20.2
0.20.1
0.20.0
0.19.1
0.19.0
0.18.3
0.18.2
0.18.1
0.18.0
0.17.7
0.17.6
0.17.5
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.2
0.16.1
0.16.0
0.15.11
0.15.10
0.15.9
0.15.8
0.15.7
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.8
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.13.0
0.12.3
0.12.2
0.12.1
0.12.0
0.11.0
0.10.3
0.10.2
0.10.1
0.10.0
0.9.0
0.9.0-rc.4
0.9.0-rc.3
0.9.0-rc.2
0.9.0-rc.1
0.9.0-rc.0
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.0
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.0
0.4.3
0.4.2
Elixir Z-Wave library
Current section
Files
Jump to
Current section
Files
lib/grizzly/virtual_devices/reports.ex
defmodule Grizzly.VirtualDevices.Reports do
@moduledoc false
# Helper module for building various general reports for a virtual device
alias Grizzly.{Report, VirtualDevices, VirtualDevicesRegistry}
alias Grizzly.ZWave.{Command, DeviceClass, DSK}
alias Grizzly.ZWave.Commands.{
AssociationReport,
BatteryReport,
ManufacturerSpecificDeviceSpecificReport,
ManufacturerSpecificReport,
NodeAddStatus,
NodeInfoCacheReport,
NodeRemoveStatus,
VersionCommandClassReport,
VersionReport
}
@doc """
Send the node add status message to the handler
"""
@spec send_node_add_status(VirtualDevicesRegistry.device_entry(), Grizzly.handler()) :: :ok
def send_node_add_status(device_entry, handler) do
{handler, handler_opts} = ensure_handler_with_opts(handler)
{:ok, node_add_status} =
NodeAddStatus.new(
seq_number: 0x00,
node_id: device_entry.id,
status: :done,
listening?: true,
basic_device_class: device_entry.device_class.basic_device_class,
generic_device_class: device_entry.device_class.generic_device_class,
specific_device_class: device_entry.device_class.specific_device_class,
command_classes: command_classes_for_device(device_entry.device_class),
granted_keys: [],
kex_fail_type: :none,
input_dsk: DSK.new("")
)
report = Report.new(:complete, :command, device_entry.id, command: node_add_status)
handler.handle_report(report, handler_opts)
:ok
end
def send_node_remove_status(device_id, handler) do
{handler, handler_opts} = ensure_handler_with_opts(handler)
{:ok, node_remove_status} =
NodeRemoveStatus.new(seq_number: 0x01, status: :done, node_id: device_id)
report = Report.new(:complete, :command, device_id, command: node_remove_status)
handler.handle_report(report, handler_opts)
:ok
end
defp ensure_handler_with_opts(handler_spec) when is_tuple(handler_spec), do: handler_spec
defp ensure_handler_with_opts(handler_module) when is_atom(handler_module),
do: {handler_module, []}
@doc """
Build a node info cached report based of a node info get command
"""
@spec build_node_info_cache_report(VirtualDevicesRegistry.device_entry(), Command.t()) ::
Report.t()
def build_node_info_cache_report(entry, node_info_get) do
seq_number = Command.param!(node_info_get, :seq_number)
{:ok, node_info_report} =
NodeInfoCacheReport.new(
seq_number: seq_number,
status: :ok,
age: 1,
listening?: true,
command_classes: command_classes_for_device(entry.device_class),
basic_device_class: entry.device_class.basic_device_class,
specific_device_class: entry.device_class.specific_device_class,
generic_device_class: entry.device_class.generic_device_class
)
Report.new(:complete, :command, entry.id, command: node_info_report)
end
@doc """
Build manufacturer specific report for the device entry
"""
@spec build_manufacturer_specific_report(VirtualDevicesRegistry.device_entry()) :: Report.t()
def build_manufacturer_specific_report(entry) do
{:ok, manufacturer_report} =
ManufacturerSpecificReport.new(
manufacturer_id: entry.device_class.manufacturer_id,
product_id: entry.device_class.product_id,
product_type_id: entry.device_class.product_type_id
)
Report.new(:complete, :command, entry.id, command: manufacturer_report)
end
@doc """
Build version command class get for a command class in the entry's device
class
"""
@spec build_version_command_class_get_report(VirtualDevicesRegistry.device_entry(), Command.t()) ::
Report.t()
def build_version_command_class_get_report(entry, version_command_class_get) do
command_class = Command.param!(version_command_class_get, :command_class)
case DeviceClass.get_command_class_version(entry.device_class, command_class) do
nil ->
build_timeout_report(entry.id)
version ->
{:ok, version_report} =
VersionCommandClassReport.new(command_class: command_class, version: version)
build_report(entry, version_report)
end
end
@doc """
Build the association report from the association get command
"""
@spec build_association_report(VirtualDevicesRegistry.device_entry()) :: Report.t()
def build_association_report(entry) do
{:ok, report} =
AssociationReport.new(
nodes: [1],
grouping_identifier: 1,
max_nodes_supported: 1,
reports_to_follow: 0
)
build_report(entry, report)
end
@doc """
Build a battery report for a battery get command
"""
@spec build_battery_report(VirtualDevicesRegistry.device_entry()) :: Report.t()
def build_battery_report(entry) do
{:ok, report} = BatteryReport.new(level: 100)
build_report(entry, report)
end
@doc """
Build a version report for a version get command
"""
@spec build_version_report(VirtualDevicesRegistry.device_entry()) :: Report.t()
def build_version_report(entry) do
{:ok, report} =
VersionReport.new(
library_type: entry.device_class.library_type,
protocol_version: "7.16",
firmware_version: "7.16",
hardware_version: 1,
other_firmware_versions: ["7.16"]
)
build_report(entry, report)
end
def build_manufacturer_specific_device_specific_report(entry, command) do
case Command.param!(command, :device_id_type) do
:serial_number ->
{:ok, report} =
ManufacturerSpecificDeviceSpecificReport.new(
device_id_type: :serial_number,
device_id: "0000"
)
build_report(entry, report)
_other ->
build_timeout_report(entry.id)
end
end
@doc """
Build a Grizzly Report for a timeout
"""
@spec build_timeout_report(VirtualDevices.id()) :: Report.t()
def build_timeout_report(device_id) do
Report.new(:complete, :timeout, device_id)
end
@doc """
Build an ack response report
"""
@spec build_ack_response(VirtualDevicesRegistry.device_entry()) :: Report.t()
def build_ack_response(entry) do
Report.new(:complete, :ack_response, entry.id)
end
@doc """
Build a report that contains a command
"""
@spec build_report(VirtualDevicesRegistry.device_entry(), Command.t()) :: Report.t()
def build_report(entry, command) do
Report.new(:complete, :command, entry.id, command: command)
end
defp command_classes_for_device(device_class) do
[
non_secure_supported: Map.keys(device_class.command_classes.support),
non_secure_controlled: Map.keys(device_class.command_classes.control)
]
end
end