Dynamic Lists and Filters¶
You may create dynamic menus and lists that are created at runtime. Indigo will supply some specific ones for you or your plugin may be called each time the UI is presented that will allow you to return anything you like.
To specify a dynamic list, you add some attributes to the List element and skip adding Option elements. To request any of the built-in lists, you specify a class attribute and (optionally) a filter attribute. For example, this field:
<Field id="insteonDimmers" type="menu">
<Label>Insteon Dimmers:</Label>
<List class="indigo.devices" filter="indigo.dimmer,indigo.insteon"/>
</Field>
would request a list of all Insteon dimmer devices. The list would be constructed with the device name as the menu or list item viewable by the user, and the value would be the device ID.
Attributes
| Attributes | ||
|---|---|---|
| Attribute | Required | Notes |
class |
Yes | A reference to a class value as described below. The class attribute must be set to one or more of the built-in classes (listed below), or self. |
filter |
No | A filter attribute is not required, but if one is included, it must be set to a valid filter (see below) or empty filter="". |
method |
No | A reference to a plugin.py method that returns the list elements as described below. If not included, class must refer to one of the built-in methods (class="self" by itself will not work). |
Device Filters
The indigo.devices class specifies that the list will contain Indigo devices. If you don’t specify a filter, all devices defined by the user in Indigo will be returned. You can supply up to two filters if and only if one is an interface filter (see the first three in the list below). The filters are ANDed together, so one interface filter and one device type filter are the only combinations that will result in a non-empty list.
Class: indigo.devices |
|
|---|---|
| Optional Filters | Description |
indigo.zwave |
include Z-Wave devices - this is an interface filter that can be used with other filters |
indigo.insteon |
include Insteon devices - this is an interface filter that can be used with other filters |
indigo.x10 |
include X10 devices - this is an interface filter that can be used with other filters |
indigo.responder |
include devices whose state can be changed |
indigo.controller |
include devices that can send commands |
indigo.relay |
relay devices |
indigo.dimmer |
dimmer devices |
indigo.sprinkler |
sprinklers |
indigo.thermostat |
thermostats |
indigo.iodevice |
input/output devices |
indigo.sensor |
all sensor type devices: motion sensors, TriggerLinc, SynchroLinc (sensor devices that have a virtual state in Indigo) |
self |
all device types defined by the calling plugin |
self.devTypeId |
all devices of type deviceTypeId, where deviceTypeId is one of the device types specified by the calling plugin |
com.somePlugin |
all device types defined by some other plugin |
com.somePlugin.devTypeId |
all devices of type deviceTypeId, where deviceTypeId is one of the device types specified in some other plugin |
The indigo.triggers class specifies that the list will contain Indigo triggers. Only a single filter from the list below will return a useful list.
Trigger Filters
Class: indigo.triggers |
|
|---|---|
| Optional Filters | Description |
indigo.insteonCmdRcvd |
Insteon command received triggers |
indigo.x10CmdRcvd |
x10 command received triggers |
indigo.devStateChange |
device state changed triggers |
indigo.varValueChange |
variable changed triggers |
indigo.serverStartup |
startup triggers |
indigo.powerFailure |
power failure triggers |
indigo.interfaceFail |
interface failure triggers - can be used with or without a specified protocol |
indigo.interfaceInit |
interface connection triggers - can be used with or without a specified protocol |
indigo.emailRcvd |
email received triggers |
Using the indigo.schedules class will result in a list of all schedules, as will indigo.actionGroups and indigo.controlPages for their respective object types. None of these classes support any kind of filter. Lastly, indigo.variables will get you a list of variables. If you include filter="indigo.readWrite", you’ll get only variables for which you can change the value. Currently, there’s only one read-only variable (isDaylight) defined by the system, but it may be possible to create them in future versions of the API.
Another special built-in list is serial ports - use indigo.serialPorts to get a list of available serial ports, and what's returned to your plugin is the full path to the plugin (e.g. "/dev/tty*"). This is suitable for using with PySerial, which we include with Indigo. See the "serialport" field type below for an even better way of collecting serial communication information.
You may also include custom dynamic lists that are constructed on-the-fly by your plugin. If you defined your list like this:
<Field id="insteonDimmers" type="menu">
<Label>Insteon Dimmers:</Label>
<List class="self" filter="stuff" method="myListGenerator"/>
</Field>
Then your plugin will have the method specified called with the filter. For the above example, you must define a method like this:
def myListGenerator(self, filter="", valuesDict=None, typeId="", targetId=0):
# From the example above, filter = "stuff"
# You can pass anything you want in the filter for any purpose
# Create a list where each entry is a list - the first item is
# the value attribute and last is the display string that will
# show up in the control. All parameters are read-only.
myArray = [("option1", "First Option"),("option2","Second Option")]
return myArray
Note
Both return tuple values should be strings. Specifically, items with None as the value (first item) will be skipped. Additionally, the first tuple value (option1 and option2 in the above example) must be a string that does not contain comma or semicolon characters.
The valuesDict parameter will contain the valuesDict for the object being edited - if it's a device config UI then it'll be the valuesDict from that device (just like what's passed in to validation methods), etc. Note: if it's a new object that hasn't been saved yet, valuesDict may be None or empty so test accordingly.
The typeId parameter will contain the type - for instance, if it's an event, it will be the event type id. The targetId is the ID of the object being edited. It will be 0 if it's a new object that hasn't been saved yet.
The field would then be created as if you had specified it statically like this:
<Field id="customList" type="menu">
<Label>Select an Option:</Label>
<List>
<Option value="option1">First Option</Option>
<Option value="option2">Second Option</Option>
</List>
</Field>
This mechanism allows you to create any number of lists: devices dynamically discovered through some discovery protocol, calendars available, email addresses, iTunes playlists, etc.
One further option to dynamic lists is the ability to have them reload whenever the config dialog returns from a button or menu callback. So, for instance, if you have a button that somehow changes the contents of the dynamic list, you can specify the list as a one that's dynamically reloaded:
<Field id="insteonDimmers" type="menu">
<Label>Insteon Dimmers:</Label>
<List class="self" filter="stuff" method="myListGenerator" dynamicReload="true"/>
</Field>
Note
This will cause an extra round-trip (client->Indigo server->plugin->Indigo server->client) so you should only use this when the list can change while the dialog is actually running.