# `Grizzly.VirtualDevices`
[🔗](https://github.com/smartrent/grizzly/blob/v9.1.4/lib/grizzly/virtual_devices.ex#L1)

Virtual devices

Virtual devices are in-memory devices that act like a Z-Wave device

# `add_opt`

```elixir
@type add_opt() ::
  {:inclusion_handler, Grizzly.handler()}
  | Grizzly.VirtualDevices.Device.device_opt()
```

Options for adding a virtual devices

* `:inclusion_handler` - if an inclusion handler is provider via the add
  options it will override the initial inclusion handle argument to the
  network server if one was provided only for that one call to `add_device/2`.

You may also include other device options that will passed to your callback
functions for implementation specific support.

# `device_entry`

```elixir
@type device_entry() :: %{
  device_impl: Grizzly.VirtualDevices.Device.t(),
  device_class: Grizzly.ZWave.DeviceClass.t(),
  device_opts: [Grizzly.VirtualDevices.Device.device_opt()],
  id: id(),
  pid: pid()
}
```

# `id`

```elixir
@type id() :: {:virtual, non_neg_integer()}
```

Id for a virtual device

# `remove_opt`

```elixir
@type remove_opt() :: {:inclusion_handler, Grizzly.handler()}
```

Options for removing virtual devices

* `:inclusion_handler` - if an inclusion handler is provider via the add
  options it will override the initial inclusion handle argument to the
  network server if one was provided only for that one call to
  `remove_device/2`.

# `add_device`

```elixir
@spec add_device(id(), Grizzly.VirtualDevices.Device.t(), [add_opt()]) ::
  {:ok, id()} | {:error, {:already_registered, device_entry()}}
```

Add a new virtual device to the virtual device network

To add a virtual device you must supply a module that implements the
`Grizzly.VirtualDevices.Device` behaviour.

If the device takes any options you can pass a tuple of `{device, opts}`.

# `add_device!`

```elixir
@spec add_device!(id(), Grizzly.VirtualDevices.Device.t(), [add_opt()]) :: id()
```

Same as `add_device/3` but raises an ArgumentError if a device with the requested
id is already registered.

# `broadcast_command`

```elixir
@spec broadcast_command(id(), Grizzly.ZWave.Command.t()) :: :ok
```

Broadcast a command to the rest of the Z-Wave network

# `get_device`

```elixir
@spec get_device(id()) :: device_entry() | nil
```

Get a virtual device's configuration.

# `list_nodes`

```elixir
@spec list_nodes() :: [id()]
```

List the nodes in the virtual devices network

# `remove_device`

```elixir
@spec remove_device(id(), [remove_opt()]) :: :ok
```

Remove a device from the virtual device network

# `send_command`

```elixir
@spec send_command(id(), Grizzly.ZWave.Command.t()) ::
  {:ok, Grizzly.Report.t()} | {:error, :device_not_found | Grizzly.Report.t()}
```

Send a Z-Wave command to the virtual device

# `whereis`

```elixir
@spec whereis(id()) :: pid() | nil
```

Get the pid for the device id

This is useful for when you device is processed-based and you need to send
messages to it.

---

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