# Device

## Definition

A private **device** plugin lets Ubidots developers create custom devices with a native Ubidots experience. Unlike Ubidots native devices, these plugins let you define custom *categories* and *filters*. This gives you more control over how the device appears in the Devices drawer.

<figure><img src="/files/35lR0XiPvNKPDsw50bP0" alt="" width="563"><figcaption></figcaption></figure>

## Categories

Categories are set in the `manifest.toml` file and are the primary way to classify a Device plugin. In the screenshot above, categories are highlighted in red.

Each Device plugin can define its own categories, so the Devices drawer shows every category defined across your devices. If multiple devices share the same category, that category is displayed only once in the drawer and groups together all devices that define it.

For example, in the screenshot above, both devices define the `End Device` *category*. The `ALTA` device also defines the `Industrial Gateway` *category*. As a result, the drawer displays two categories:

* `End Device`
* `Industrial Gateway`

In the screenshot above, the **ALTA** device appears under two *categories* — **End Device** and **Industrial Gateway** — because a device can belong to multiple *categories* at the same time.

If the `categories` key is not specified in the `manifest.toml` file, the device is automatically added to a *category* called `plugin`.

{% hint style="warning" %}
If `categories` is specified but no value is given, the device will not be displayed.
{% endhint %}

## Filters

*Filters* are defined in the `manifest.toml` file. In the screenshot above, *filters* are highlighted in magenta.

This is the second way to classify devices and lets users define custom filters. These filters are built as key-value settings, where each value is a list of strings.

{% hint style="warning" %}
Neither *categories* nor *filters* can be used to filter devices in API requests. They only categorize devices in the drawer.
{% endhint %}

## Required files

As explained earlier, any private plugin, including a private device plugin, uses the file structure shown below:

```
├── src           
│   ├── view.xml           
├── LICENSE
├── README.md
├── manifest.toml
```

### manifest.toml <a href="#naming-convention" id="naming-convention"></a>

Aside from the manifest components shared by all plugin types, the following keys are specific to Device plugins:

<table><thead><tr><th width="121">Section/subsection</th><th width="115">Key</th><th width="161">Value</th><th width="157">Description</th><th>Example</th></tr></thead><tbody><tr><td>[settings]</td><td>categories</td><td>A list of strings</td><td>Each element in the list is the name of a category.</td><td><pre class="language-toml"><code class="lang-toml">categories = ["End Device"]
</code></pre></td></tr><tr><td>[settings]</td><td>filters</td><td><p>A dictionary with the following schema:</p><p><br><code>str: list</code></p></td><td>Each root key is the name of the filter, and its respective values are assigned to the device.</td><td><pre class="language-toml"><code class="lang-toml">filters = {brand = ["Advantech"], connectivity = ["Ethernet"]}
</code></pre></td></tr></tbody></table>

With this in mind, a typical device plugin manifest file looks like this:

```
manifest_version = 2.0

[settings]
version = "0.0.1"
plugin_type = "device"
license_name = "MIT license"
categories = ["End Device"]
filters = {brand = ["Advantech"], connectivity = ["Ethernet"]}

```

### view\.xml <a href="#view.xml" id="view.xml"></a>

This file is not currently used by Device plugins, but it must still contain valid placeholder data so the plugin can be deployed.

### LICENSE and README.md files

For more details, see [Private Plugins](/plugins/private-plugins.md).

### Naming convention <a href="#naming-convention" id="naming-convention"></a>

Keep the names of all files and directories mentioned in the previous section. The plugins engine looks specifically for those files and their extensions.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dev.ubidots.com/plugins/private-plugins/device.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
