Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
indigo_2025.1_documentation:plugin_guide [2025/10/23 23:26] – [Custom HTML Menu Item Dialogs] davel17indigo_2025.1_documentation:plugin_guide [2026/03/13 01:46] (current) – [Color Picker] davel17
Line 621: Line 621:
 === Color Picker === === Color Picker ===
  
-{{color_picker_control.png?nolink|Color Picker Control Image}}+{{:indigo_2025.1_documentation:color_picker.png?200|}}
  
-<code><Field id="exampleColorPicker" +<code><Field id="exampleColorPicker" type="colorpicker" tooltip="Click this button to select a color.">
-       type="button" +
-       tooltip="Click this button to select a color.">+
     <Label>Color:</Label>     <Label>Color:</Label>
     <CallbackMethod>ColorPickerPressed</CallbackMethod>     <CallbackMethod>ColorPickerPressed</CallbackMethod>
Line 632: Line 630:
 Color Picker fields allow your user to choose a color value. For example, you might provide a method for a user to select a color for an RGB LED device. When the user clicks the color button, Indigo will open the standard macOS color selector dialog. Color Picker fields allow your user to choose a color value. For example, you might provide a method for a user to select a color for an RGB LED device. When the user clicks the color button, Indigo will open the standard macOS color selector dialog.
  
-{{color_selector_dialog.png?nolink|Color Selector Dialog Image}}+{{:indigo_2025.1_documentation:color_selector.png?200|}}
  
 After the user selects a color, the color's value will be passed back to your plugin as a ''//values_dict//'' value when the user executes/closes the configuration dialog. Note that the value provided is a standard RGB value as a space-delimited string. You are responsible for converting that value into the format you need like ''//#8000FF//''. After the user selects a color, the color's value will be passed back to your plugin as a ''//values_dict//'' value when the user executes/closes the configuration dialog. Note that the value provided is a standard RGB value as a space-delimited string. You are responsible for converting that value into the format you need like ''//#8000FF//''.
Line 649: Line 647:
 |//''enabledBindingNegate''// No  |  1.9  |Set this to "true" to negate the binding. So if the target binding field's value is true then the binding will be false.  | |//''enabledBindingNegate''// No  |  1.9  |Set this to "true" to negate the binding. So if the target binding field's value is true then the binding will be false.  |
 |//''id''// Yes  |  1.0  |This is a unique identifier for this Field within the context of this //''ConfigUI''// element.| |//''id''// Yes  |  1.0  |This is a unique identifier for this Field within the context of this //''ConfigUI''// element.|
-|//''type''// Yes  |  2.0  |This must be //''colorPicker''//.|+|//''type''// Yes  |  2.0  |This must be //''colorpicker''//.|
 |//''visibleBindingId''// No  |  1.0  |If you want to conditionally show/hide this field based on the value of another field, set this value to the //''id''// of another field. If you set this, you must also include a //''visibleBindingValue''//| |//''visibleBindingId''// No  |  1.0  |If you want to conditionally show/hide this field based on the value of another field, set this value to the //''id''// of another field. If you set this, you must also include a //''visibleBindingValue''//|
 |//''visibleBindingValue''// No  |  1.0  |If you specify a //''visibleBindingId''//, you must specify the value(s) here. For instance, if you are binding to a checkbox, setting this to //''false''// will mean the menu field is visible only when the checkbox is unchecked, and a //''true''// means the opposite. To make the field dependent on another list or menu, set this value to a comma separated list of option values (//''item1, item2''//). You can even bind it to the value in a text field, but that’s probably of limited use. **Note**: the string comparison is a contains - so if any option contains the specified string it will match. This offers some extra flexibility in defining dependency groups.| |//''visibleBindingValue''// No  |  1.0  |If you specify a //''visibleBindingId''//, you must specify the value(s) here. For instance, if you are binding to a checkbox, setting this to //''false''// will mean the menu field is visible only when the checkbox is unchecked, and a //''true''// means the opposite. To make the field dependent on another list or menu, set this value to a comma separated list of option values (//''item1, item2''//). You can even bind it to the value in a text field, but that’s probably of limited use. **Note**: the string comparison is a contains - so if any option contains the specified string it will match. This offers some extra flexibility in defining dependency groups.|
Line 755: Line 753:
 === Custom HTML Config Dialogs === === Custom HTML Config Dialogs ===
  
-You can also implement your own custom configuration in HTML if you prefer. Rather than adding lots of //''<Field>''// definitions, you simply specify a //''<URL>''// element. The URL specified can either be a fully specified URL <nowiki>(protocol://host/path)</nowiki> or it may be a relative URL (/some/relative/path). If it's the later then Indigo will attempt to guess the [[indigo_2022.2_documentation:server_commands&#get_web_server_url|best base URL]]. You would then handle those form requests using [[#processing_http_requests_in_your_plugin|the built-in request handling mechanism discussed below]]. See the **Example HTTP Responder** plugin in the [[https://github.com/IndigoDomotics/IndigoSDK/releases/tag/v2024.1|SDK]] for an example.+You can also implement your own custom configuration in HTML if you prefer. Rather than adding lots of //''<Field>''// definitions, you simply specify a //''<URL>''// element. The URL specified can either be a fully specified URL <nowiki>(protocol://host/path)</nowiki> or it may be a relative URL (/some/relative/path). If it's the later then Indigo will attempt to guess the [[indigo_2022.2_documentation:server_commands&#get_web_server_url|best base URL]]. You would then handle those form requests using [[#processing_http_requests_in_your_plugin|the built-in request handling mechanism discussed below]]. See the **Example HTTP Responder** plugin in the [[https://github.com/IndigoDomotics/IndigoSDK/releases/tag/v2025.1|SDK]] for an example.
 ==== Devices.xml ==== ==== Devices.xml ====
  
Line 767: Line 765:
 |//''type''// Attribute  |  Yes  |This must be one of: //''dimmer''//, //''relay''//, //''sensor''//, //''speedcontrol''//,  //''thermostat''//, or //''custom''//. We’ll discuss each below.| |//''type''// Attribute  |  Yes  |This must be one of: //''dimmer''//, //''relay''//, //''sensor''//, //''speedcontrol''//,  //''thermostat''//, or //''custom''//. We’ll discuss each below.|
 |//''id''// Attribute  |  Yes  |This is your plugins unique identifier for this device type. It must be unique in this plugin.| |//''id''// Attribute  |  Yes  |This is your plugins unique identifier for this device type. It must be unique in this plugin.|
-|//''subType''// Attribute  |  No  |This must be one of: //''kDimmerDeviceSubType''//, //''kRelayDeviceSubType''//, //''kSensorDeviceSubType''//. We’ll discuss each below. There are also several device //''SubType''// examples in the [[https://github.com/IndigoDomotics/IndigoSDK/releases/tag/v2024.1|SDK]]. |+|//''subType''// Attribute  |  No  |This must be one of: //''kDimmerDeviceSubType''//, //''kRelayDeviceSubType''//, //''kSensorDeviceSubType''//. We’ll discuss each below. There are also several device //''SubType''// examples in the [[https://github.com/IndigoDomotics/IndigoSDK/releases/tag/v2025.1|SDK]]. |
 |//''allowUserCreation''// Attribute  |  No  |If set, the value must either be //''true''// or //''false''// (defaults to //''true''//). This attribute is discussed in more detail below.  | |//''allowUserCreation''// Attribute  |  No  |If set, the value must either be //''true''// or //''false''// (defaults to //''true''//). This attribute is discussed in more detail below.  |
 |//''Name''// Element  |  Yes  |This is the name of the device type that users will see when selecting the type in the Devices dialog.| |//''Name''// Element  |  Yes  |This is the name of the device type that users will see when selecting the type in the Devices dialog.|
Line 829: Line 827:
 <Device type="sensor" subType="kSensorDeviceSubType.Temperature, ui=Outdoor Temperature" id="my_temp_sensor", allowUserCreation="false"> <Device type="sensor" subType="kSensorDeviceSubType.Temperature, ui=Outdoor Temperature" id="my_temp_sensor", allowUserCreation="false">
 </code> </code>
-Check out the [[https://github.com/IndigoDomotics/IndigoSDK/releases/tag/v2024.1|SDK]] for example plugins of each type of device listed above. The examples show config dialogs, required method stubs, etc., to implement the respective device types.+Check out the [[https://github.com/IndigoDomotics/IndigoSDK/releases/tag/v2025.1|SDK]] for example plugins of each type of device listed above. The examples show config dialogs, required method stubs, etc., to implement the respective device types.
  
-> **IMPORTANT:** Plugin developers should account for each devices' callbacks when implementing built-in device types -- even if you don't use all the callbacks within your plugin. For example, if your plugin implements the //''Speed Control''// device type, your plugin should include handlers for all the Speed Control callbacks -- such as //''turnOn''//, //''turnOff''//, or //''toggle''//. This is very important because these callbacks will still be exposed in the Indigo Client UI for things like Actions and Triggers. It's best to give users an indication that the callback won't do anything in your plugin by writing a warning to the Event log. Consult the [[https://github.com/IndigoDomotics/IndigoSDK/releases/tag/v2024.1|SDK]] for more information on each device types' callbacks and examples of how to handle them.+> **IMPORTANT:** Plugin developers should account for each devices' callbacks when implementing built-in device types -- even if you don't use all the callbacks within your plugin. For example, if your plugin implements the //''Speed Control''// device type, your plugin should include handlers for all the Speed Control callbacks -- such as //''turnOn''//, //''turnOff''//, or //''toggle''//. This is very important because these callbacks will still be exposed in the Indigo Client UI for things like Actions and Triggers. It's best to give users an indication that the callback won't do anything in your plugin by writing a warning to the Event log. Consult the [[https://github.com/IndigoDomotics/IndigoSDK/releases/tag/v2025.1|SDK]] for more information on each device types' callbacks and examples of how to handle them.
  
 === Custom Device Type === === Custom Device Type ===
Line 1250: Line 1248:
 === Custom HTML Menu Item Dialogs === === Custom HTML Menu Item Dialogs ===
  
-You can also implement your own custom menu item form in HTML if you prefer. Rather than adding //''<CallbackMethod>''// and  //''<ConfigUI>''// definitions, you simply specify a //''<URL>''// element. The URL specified can either be a fully specified URL <nowiki>(protocol://host/path)</nowiki> or it may be a relative URL (/some/relative/path). If it's the latter, then Indigo will attempt to guess the [[indigo_2025.1_documentation:server_commands&#get_web_server_url|best base URL]]. You would then handle those form requests using [[#processing_http_requests_in_your_plugin|the built-in request handling mechanism discussed below]]. See the **Example HTTP Responder** plugin in the [[https://github.com/IndigoDomotics/IndigoSDK/releases/tag/v2024.1|SDK]] for an example.+You can also implement your own custom menu item form in HTML if you prefer. Rather than adding //''<CallbackMethod>''// and  //''<ConfigUI>''// definitions, you simply specify a //''<URL>''// element. The URL specified can either be a fully specified URL <nowiki>(protocol://host/path)</nowiki> or it may be a relative URL (/some/relative/path). If it's the latter, then Indigo will attempt to guess the [[indigo_2025.1_documentation:server_commands&#get_web_server_url|best base URL]]. You would then handle those form requests using [[#processing_http_requests_in_your_plugin|the built-in request handling mechanism discussed below]]. See the **Example HTTP Responder** plugin in the [[https://github.com/IndigoDomotics/IndigoSDK/releases/tag/v2025.1|SDK]] for an example.
  
 ==== SupportURL Elements ==== ==== SupportURL Elements ====
Line 1313: Line 1311:
 |<code>deviceDeleted(self, |<code>deviceDeleted(self,
               dev)</code> No  |Complementary to the ''//deviceCreated() method//'' described above, but signals device deletes. The default implementation just checks to see if the device belongs to your plugin and if so calls the ''//deviceStopComm()//'' method. If you implement this method you'll need to call ''//deviceStopComm()//'' yourself or duplicate the functionality here.|               dev)</code> No  |Complementary to the ''//deviceCreated() method//'' described above, but signals device deletes. The default implementation just checks to see if the device belongs to your plugin and if so calls the ''//deviceStopComm()//'' method. If you implement this method you'll need to call ''//deviceStopComm()//'' yourself or duplicate the functionality here.|
 +|<code>getDeviceConfigUiValues(self, pluginProps, typeId, devId)</code> No  |This method will get called whenever an Device configuration is opened. Indigo will look for this method and, if it exists, will pre-populate the configuration dialog with the information created/modified in the method. This method is particularly helpful when you want an Device's configuration to be different from the default (set in the Device configuration XML file). A simple example is provided below.|
 +
 +==== getDeviceConfigUiValues Example ====
 +Here is an example of the ''** getDeviceConfigUiValues**'' method's mechanics:
 +<code>
 +def getDeviceConfigUiValues(self, pluginProps, typeId, devId):
 +        valuesDict = indigo.Dict(pluginProps)
 +        errorsDict = indigo.Dict()
 +
 +        if len(valuesDict) == 0:
 +            if typeId == "foo":
 +                valuesDict["bar"] = "123"
 +
 +        return (valuesDict, errorsDict)
 +</code>
  
 === Trigger Specific Methods === === Trigger Specific Methods ===
Line 1337: Line 1350:
 === Action Group Specific Methods === === Action Group Specific Methods ===
 ^  Name  ^  Required  ^  Notes  ^ ^  Name  ^  Required  ^  Notes  ^
 +|<code> getActionConfigUiValues(self, pluginProps, typeId, devId)</code> No  |This method will get called whenever an Action configuration is opened. Indigo will look for this method and, if it exists, will pre-populate the configuration dialog with the information created/modified in the method. This method is particularly helpful when you want an Action's configuration to be different from the default (set in the Actions configuration XML file). A simple example is provided below.|
 +
 +==== getActionConfigUiValues Example ====
 +Here is an example of the ''** getActionConfigUiValues**'' method's mechanics:
 +<code>
 +def getActionConfigUiValues(self, pluginProps, typeId, devId):
 +        valuesDict = indigo.Dict(pluginProps)
 +        errorsDict = indigo.Dict()
 +
 +        if len(valuesDict) == 0:
 +            if typeId == "foo":
 +                valuesDict["bar"] = "123"
 +
 +        return (valuesDict, errorsDict)
 +</code>
 |FIXME add action group documentation when it is complete (not currently available)||| |FIXME add action group documentation when it is complete (not currently available)|||
  
Line 1596: Line 1624:
 |''url_query_args'' | if there were any query args on the URL line, they will be in this dictionary if it exists. | |''url_query_args'' | if there were any query args on the URL line, they will be in this dictionary if it exists. |
 |''request_body'' | this will be the contents of the body of the HTTP request. It won't exist if the request was a **GET** or a **POST** //without any body//. | |''request_body'' | this will be the contents of the body of the HTTP request. It won't exist if the request was a **GET** or a **POST** //without any body//. |
-|''file_path'' | this will be a list of path parts from the URL after the action ID. So for the url: ''%%http://host/message/pluginid/actionid/path/to/some/file.txt%%'' the value will be an ''indigo.List'' with the following items: ''%%["path", "to", "some", "file.txt"]%%'' |+|''file_path'' | this will be a list of path parts from the URL after the action ID. So for the url: //''http://host/message/pluginid/actionid/path/to/some/file.txt''// the value will be an ''indigo.List'' with the following items: //''["path", "to", "some", "file.txt"]''// |
  
 <color blue>**Note**</color>: the dicts mentioned above will all be //indigo.Dict// objects, not standard Python dicts. <color blue>**Note**</color>: the dicts mentioned above will all be //indigo.Dict// objects, not standard Python dicts.
Line 1652: Line 1680:
  
 ===== Event and Message Flow ===== ===== Event and Message Flow =====
-Under some circumstances, the Indigo Server will send callbacks to your plugin based on events that take place. For example, if your plugin devices expose features like Turn On, Turn Off or Status Request, Indigo will send a callback to your plugin so you can take actions on these events. There are many different callbacks that can occur which are documented extensively in the [[https://github.com/IndigoDomotics/IndigoSDK/releases/tag/v2024.1|SDK]].+Under some circumstances, the Indigo Server will send callbacks to your plugin based on events that take place. For example, if your plugin devices expose features like Turn On, Turn Off or Status Request, Indigo will send a callback to your plugin so you can take actions on these events. There are many different callbacks that can occur which are documented extensively in the [[https://github.com/IndigoDomotics/IndigoSDK/releases/tag/v2025.1|SDK]].
  
 Here is a simple example showing how to handle these callbacks (consult the [[https://github.com/IndigoDomotics/IndigoSDK/releases|SDK]] for a detailed example that relates to your device's class). Here is a simple example showing how to handle these callbacks (consult the [[https://github.com/IndigoDomotics/IndigoSDK/releases|SDK]] for a detailed example that relates to your device's class).
  • /www/perceptive/wiki/data/attic/indigo_2025.1_documentation/plugin_guide.1761262006.txt.gz
  • Last modified: 2025/10/23 23:26
  • by davel17