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_5_documentation:trigger_class [2013/09/01 17:32]
127.0.0.1 external edit
indigo_5_documentation:trigger_class [2019/01/25 22:53] (current)
Line 1: Line 1:
 +====== Triggers ======
  
 +In the IOM, all triggers are derived from a common Trigger base class. This base contains all the shared components of triggers.
 +===== Trigger Base Class =====
 +
 +All triggers will inherit properties from the Trigger base class - including plugin defined events. Note: plugin defined events will always return False for the upload property.
 +
 +Like other high-level objects in Indigo, there are rules for modifying triggers. For Scripters and Plugin Developers:
 +
 +  - To create, duplicate, delete, and send commands to a trigger, use the command namespace as described below
 +  - To modify an object'​s definition get a copy of the trigger, make the necessary changes, then call //''​myTrigger.replaceOnServer(newPropsDict)''//​
 +
 +For Plugin Developers:
 +
 +  - To update a plugin'​s props on a trigger, call //''​myTrigger.replacePluginPropsOnServer(newPropsDict)''//​ rather than try to update them on the local trigger
 +
 +Unlike [[device_class|Devices]],​ you can't call //''​create()''//​ in the the trigger base class command namespace (//''​indigo.trigger.*''//​). Rather, each subclass has it's own //''​create()''//​ method that takes the appropriate arguments for that trigger type.
 +
 +==== Firing Plugin Defined Triggers ====
 +
 +If you are a plugin developer and your plugin defines events, The process for executing your plugin'​s events is this:
 +
 +  - User creates a trigger of type plugin and selects one of your plugin events - configures it (if necessary) and saves.
 +  - Indigo Server sends the new trigger object to your plugin via the various Trigger Specific Methods in **''​plugin.py''​**. The easiest one (parallel to the various device events) is //''​triggerStartProcessing(self,​ trigger)''//​. This method is also called when the server first starts up your plugin - it will pass all triggers defined to your plugin, one at a time, through this method.
 +  - Your trigger catches the trigger passed in that method and stores it so that it can watch for the conditions that define the event.
 +  - When the conditions are met that would cause that trigger to fire (plugin implementation specific), you tell the server to [[#​execute_trigger|execute the trigger]] using the //''​indigo.trigger.execute(triggerRef)''//​ method. Note that the execute method will allow you to optionally bypass any conditions - you should NOT do this unless you're providing some kind of override/​bypass. Users will clearly want conditions to be taken into account under normal circumstances (that'​s the default behavior).
 +
 +You will also need to implement //''​triggerStopProcessing(self,​trigger)''//​ so that you can remove disabled/​deleted triggers from your watch list. So, the Server isn't really involved at all with the trigger firing (except to execute the trigger when you tell it to) - it only notifies your plugin of events it's supposed to be watching for and your plugin does the rest.
 +
 +==== Class Properties ====
 +
 +^  Property ​ ^  Type  ^  Writable ​ ^  Description ​ ^
 +|//''​actions''//​| ​ list of [[action_class|Action]] ​ |  Yes  |a list of Action objects (action steps in AS) that are executed for this trigger|
 +|//''​description''//​| ​ string ​ |  Yes  |description of the trigger|
 +|//''​enabled''//​| ​ boolean ​ |  Yes  |true if this trigger is enabled|
 +|//''​folderId''//​| ​ integer ​ |  No  |unique ID of the folder this trigger is in|
 +|//''​globalProps''//​| ​ dictionary ​ |  No  |an //''​indigo.Dict()''//​ representing all name/value pairs associated with this trigger - each plugin will have it's own dictionary (//''​globalProps[pluginId]''//​) - see [[#​about_plugin_properties|About Plugin Properties]] below for details|
 +|//''​id''//​| ​ integer ​ |  No  |a unique id of the trigger, assigned on creation by IndigoServer - not available in AppleScript|
 +|//''​name''//​| ​ string ​ |  Yes  |the unique name of the trigger - no two triggers can have the same name|
 +|//''​pluginProps''//​| ​ dictionary ​ |  No  |an //''​indigo.Dict()''//​ representing the name/value pairs defined by your plugin for the trigger - plugin developers should publish this information if you want other plugins/​scripts to create triggers of this type - see [[#​about_plugin_properties|About Plugin Properties]] below for details|
 +|//''​suppressLogging''//​| ​ boolean ​ |  Yes  |true if execution of this trigger will not be logged into the event log|
 +|//''​upload''//​| ​ boolean ​ |  Yes  |true if IndigoServer should attempt to upload this trigger to the interface - will always be false for plugin triggers|
 +
 +==== About Plugin Properties ====
 +
 +Triggers have properties - some are class properties, defined by the class itself. One of the biggest requests we've gotten in the past is some way to add arbitrary properties to an object - so that you could store your own data with the object in the database. And with plugin defined triggers, we needed a place to store the properties that you need to operate the trigger. That's what the //''​pluginProps''//​ and //''​globalProps''//​ represent - the additional properties that are not defined by the class. //''​globalProps''//​ is a dictionary of every additional property defined for the trigger - each plugin has it's own dictionary of props in here which are readable by anyone. //''​pluginProps''//​ is a shortcut to get to your plugin'​s props and are only writable by your plugin.
 +
 +We mentioned before that triggers were read-only, and that's true, and that you'd need to use commands in a different command name space. That's //​**mostly**//​ true. Here's another exception to that rule: to change a trigger'​s pluginProps (it must be "​owned"​ by your plugin - that is, the pluginId must be set to your id), you use a method that's in the trigger'​s class: replacePluginPropsOnServer(). Here's an example:
 +
 +<​code>​trigger=indigo.triggers[123]
 +localPropsCopy = trigger.pluginProps
 +localPropsCopy["​pollInterval"​] = 10
 +trigger.replacePluginPropsOnServer(localPropsCopy)</​code>​
 +
 +You would use this technique if you wanted to just change some of the properties that are already defined. Because this method replaces ALL of the properties for your plugin in the trigger, you can just set them all in one call:
 +
 +<​code>​trigger=indigo.triggers[123]
 +trigger.replacePluginPropsOnServer({"​prop1":​10,"​prop2":​True})</​code>​
 +
 +Note, though, that if you have a //''<​ConfigUI>''//​ defined for the event, those properties are also stored here - so in order to make sure your trigger works correctly you must include those properties as well. If you need to update several properties in your props dict, you can use the //''​update()''//​ method:
 +
 +<​code>​trigger=indigo.triggers[123]
 +localPropsCopy = trigger.pluginProps
 +localPropsCopy.update({"​prop1":​10,"​prop2":​True})
 +trigger.replacePluginPropsOnServer(localPropsCopy)</​code>​
 +
 +The //''​update()''//​ method will change the properties specified, and add the property if it doesn'​t exist. Now, you might be wondering - why do the extra //''​localPropsCopy = trigger.pluginProps''//​ rather than just modify the props in place:
 +
 +<​code>​trigger=indigo.triggers[123]
 +trigger.pluginProps.update({"​prop1":​10,"​prop2":​True})
 +trigger.replacePluginPropsOnServer(trigger.pluginProps)</​code>​
 +
 +Because the trigger object is read-only - when you reference //''​trigger.pluginProps''//,​ it returns a copy rather than returning a reference to the read-only object. So, in effect, you'd be modifying a copy. But, because you aren't saving a reference to that copy, it goes away since the next time you reference //''​trigger.pluginProps''//​ another copy is made.
 +
 +If you need to just dump all the properties for a trigger, you can just:
 +
 +<​code>​trigger=indigo.triggers[123]
 +trigger.replacePluginPropsOnServer(None)</​code>​
 +
 +That will completely remove your properties from the trigger.
 +
 +==== Commands (indigo.trigger.*) ====
 +
 +The commands in this section are common to all triggers regardless of type.
 +
 +=== Delete ===
 +
 +Delete the specified trigger regardless of it’s type.
 +
 +^  Command Syntax Examples ​ ^
 +|<​code>​indigo.trigger.delete(123)</​code>​|
 +
 +^  Parameters ​ ^^^^
 +^  Parameter ​ ^  Required ​ ^  Type  ^  Description ​ ^
 +|direct parameter| ​ Yes  |integer|id or instance of the trigger to delete|
 +
 +=== Duplicate ===
 +
 +Duplicate the specified trigger regardless of the type. This method returns a copy of the new trigger.
 +
 +^  Command Syntax Examples ​ ^
 +|<​code>​indigo.trigger.duplicate(123,​ duplicateName="​New Name"​)</​code>​|
 +
 +^  Parameters ​ ^^^^
 +^  Parameter ​ ^  Required ​ ^  Type  ^  Description ​ ^
 +|direct parameter| ​ Yes  |  integer ​ |id or instance of the trigger to duplicate|
 +|''//​duplicateName//''​| ​ No  |  string ​ |name for the newly duplicated trigger|
 +
 +=== Enable/​Disable Trigger ===
 +
 +Disables or enables the trigger, optionally delaying for some period of time and optionally toggling back after the given period.
 +
 +^  Command Syntax Examples ​ ^
 +|<​code>​indigo.trigger.enable(12,​value=False)</​code>​|
 +|<​code>​indigo.trigger.enable(12,​value=True)</​code>​|
 +|<​code>​indigo.trigger.enable(12,​ value=True, duration=360,​ delay=60)</​code>​|
 +
 +^  Parameters ​ ^^^^
 +^  Parameter ​ ^  Required ​ ^  Type  ^  Description ​ ^
 +|direct parameter| ​ Yes  |  integer ​ |id or instance of the trigger |
 +|''//​value//''​| ​ Yes  |  boolean ​ |True to enable, False to disable|
 +|''//​delay//''​| ​ No  |  integer ​ |number of seconds to delay before disabling or enabling the trigger|
 +|''//​duration//''​| ​ No  |  integer ​ |number of seconds before the trigger is switched back to it’s original state|
 +
 +=== Execute Trigger ===
 +
 +Tell the IndigoServer to execute the actions associated with the trigger. If you're plugin implements events, this is the method you'd call when the conditions for your specific event are met. If you're calling it this way, make sure you include the //''​ignoreConditions=False''//​ parameter (or don't include the parameter since False is the default) so that any conditions associated with the trigger (by the user in the UI) are evaluated.
 +
 +This method can also be called by scripters to immediately execute the actions associated with the trigger.
 +
 +^  Command Syntax Examples ​ ^
 +|<​code>​indigo.trigger.execute(123,​ ignoreConditions=False)</​code>​|
 +
 +^  Parameters ​ ^^^^
 +^  Parameter ​ ^  Required ​ ^  Type  ^  Description ​ ^
 +|direct parameter| ​ Yes  |  integer ​ |id or instance of the trigger |
 +|''//​ignoreConditions//''​| ​ No  |  boolean ​ |will ignore any conditions associated with the trigger if True (default) and will evaluate conditions if False|
 +
 +=== Move To Folder ===
 +
 +Use this command to move the trigger to a different folder. You can get a list of folder id’s by using indigo.triggers.folders,​ which will return a dictionary. The key to the dictionary is the ID, the value is the folder name.
 +
 +^  Command Syntax Examples ​ ^
 +|<​code>​indigo.trigger.moveToFolder(123,​ value=987)</​code>​|
 +
 +^  Parameters ​ ^^^^
 +^  Parameter ​ ^  Required ​ ^  Type  ^  Description ​ ^
 +|direct parameter| ​ Yes  |  integer ​ |id or instance of the trigger|
 +|''//​value//''​| ​ Yes  |  integer ​ |id or instance of the folder to move the trigger to|
 +
 +=== Remove Delayed Actions ===
 +
 +This command will remove delayed actions for the specified trigger. ​
 +
 +^  Command Syntax Examples ​ ^
 +|<​code>​indigo.trigger.removeDelayedActions(123)</​code>​|
 +
 +^  Parameters ​ ^^^^
 +^  Parameter ​ ^  Required ​ ^  Type  ^  Description ​ ^
 +|direct parameter| ​ No  |  integer ​ |id or instance of the trigger|
 +
 +==== Examples ====
 +
 +FIXME add examples of updating a trigger'​s properties
 +===== DeviceStateChangeTrigger =====
 +
 +The DeviceStateChangeTrigger class represents an event that is described by various changes to a device’s state. Built-in device types have fixed states, but plugins may define custom devices that define their own device states. Note: Controller device types can’t be used in device state change events since they have no state.
 +
 +==== Class Properties ====
 +
 +^  Property ​ ^  Type  ^  Writable ​ ^  Description ​ ^
 +|//''​deviceId''//​| ​ integer ​ |  Yes  |the unique device id|
 +|//''​stateChangeType''//​| ​ [[#​state_change_type_enumeration|kStateChange]] ​ |  Yes  |the type of state change|
 +|//''​stateSelector''//​| ​ [[#​state_selector_enumeration|kStateSelector]] ​ |  Yes  |can use either a string or one of the enumerations listed in the state selector enumeration|
 +|//''​stateSelectorIndex''//​| ​ integer ​ |  Yes  |a 0-based integer value to specify which of multiple options to monitor - see the About State Selector section below for more information|
 +|//''​stateValue''//​| ​ string ​ |  Yes  |the value the current state should be compared against - will be converted to the right type by the server|
 +
 +These events are rather complex for a variety of reasons, but the primary is that device states can be of multiple types which require a different set of controls. Indigo solves the problem by showing the right control options given the type. If your plugin is defining it’s own states, you’ll have to specify each state and it’s associated type so that Indigo will know what kind of controls to display to the user.
 +
 +For instance, a temperature reported from a thermostat may be a floating point number. Possible events that you could trigger off of would be greater than, less than, equal, not equal, or has any change. However, becomes true or becomes false doesn’t make any sense. Conversely, an I/O device with binary inputs would really only need becomes true, becomes false, and has any change. The other options don’t make sense. To help you define the appropriate state changes, we’ve created the State Change Enumeration that lists all possible state changes. ​
 +
 +However, that’s only one side of the issue. The other important concept is the state selector. In the example above, I mentioned a thermostat temperature and a binary input. I implied a single value for each, but in reality thermostats may in fact have multiple temperature sensors and I/O devices usually have multiple inputs and outputs. So, how do we specify which one?
 +
 +In AppleScript,​ we didn’t describe them particularly well, but basically we use a 1-based index into an array of possible values. So, for an I/O device, for instance, you’d refer to "​binaryInput1",​ "​binaryInput2",​ etc. Or for a sprinkler with multiple zones, it would be "​zone1",​ "​zone2",​ etc. In the Python API, we’ve made it easier when referencing these events with the introduction of the stateSelectorIndex. It’s the index into list of available "​things"​ represented by the device’s state.
 +
 +== State Change Type Enumeration ==
 +
 +^  indigo.kStateChange ​ ^^^
 +^  Value  ^  Description ​ ^  Valid for kStateSelector’s ​ ^
 +|//''​BecomesEqual''//​|''//​stateSelector//''​ becomes equal to ''//​stateValue//''​|''//​ActiveZone//''​ \\ //''​AnalogInput''//​ \\ //''​BrightnessLevel''//​ \\ //''​HumidityInput''//​ \\ //''​SensorInput''//​ \\ //''​SetpointCool''//​ \\ //''​SetpointHeat''//​ \\ //''​TemperatureInput''//​|
 +|//''​BecomesFalse''//​|''//​stateSelector//''​ becomes ''//​False//''​|''//​BinaryInput//''​ \\ //''​BinaryOutput''//​ \\ //''​HvacCoolerIsOn''//​ \\ //''​HvacFanIsOn''//​ \\ //''​HvacFanModeIsAlwaysOn''//​ \\ //''​HvacFanModeIsAuto''//​ \\ //''​HvacHeaterIsOn''//​ \\ //''​HvacOperationModeIsAuto''//​ \\ //''​HvacOperationModeIsCool''//​ \\ //''​HvacOperationModeIsHeat''//​ \\ //''​HvacOperationModeIsOff''//​ \\ //''​HvacOperationModeIsProgramAuto''//​ \\ //''​HvacOperationModeIsProgramCool''//​ \\ //''​HvacOperationModeIsProgramHeat''//​ \\ //''​OnOffState''//​ \\ //''​Zone''//​|
 +|//''​BecomesGreaterThan''//​|''//​stateSelector//''​ becomes greater than ''//​stateValue//''​|''//​AnalogInput//''​ \\ //''​BrightnessLevel''//​ \\ //''​HumidityInput''//​ \\ //''​SensorInput''//​ \\ //''​SetpointCool''//​ \\ //''​SetpointHeat''//​ \\ //''​TemperatureInput''//​|
 +|//''​BecomesLessThan''//​|''//​stateSelector//''​ becomes less than ''//​stateValue//''​|''//​AnalogInput//''​ \\ //''​BrightnessLevel''//​ \\ //''​HumidityInput''//​ \\ //''​SensorInput''//​ \\ //''​SetpointCool''//​ \\ //''​SetpointHeat''//​ \\ //''​TemperatureInput''//​|
 +|//''​BecomesNotEqual''//​|''//​stateSelector//''​ becomes not equal to ''//​stateValue//''​|''//​ActiveZone//''​ \\ //''​AnalogInput''//​ \\ //''​BrightnessLevel''//​ \\ //''​HumidityInput''//​ \\ //''​SensorInput''//​ \\ //''​SetpointCool''//​ \\ //''​SetpointHeat''//​ \\ //''​TemperatureInput''//​|
 +|//''​BecomesTrue''//​|''//​stateSelector//''​ becomes True|''//​BinaryInput//''​ \\ //''​BinaryOutput''//​ \\ //''​HvacCoolerIsOn''//​ \\ //''​HvacFanIsOn''//​ \\ //''​HvacFanModeIsAlwaysOn''//​ \\ //''​HvacFanModeIsAuto''//​ \\ //''​HvacHeaterIsOn''//​ \\ //''​HvacOperationModeIsAuto''//​ \\ //''​HvacOperationModeIsCool''//​ \\ //''​HvacOperationModeIsHeat''//​ \\ //''​HvacOperationModeIsOff''//​ \\ //''​HvacOperationModeIsProgramAuto''//​ \\ //''​HvacOperationModeIsProgramCool''//​ \\ //''​HvacOperationModeIsProgramHeat''//​ \\ //''​OnOffState''//​ \\ //''​Zone''//​|
 +|//''​Changes''//​|''//​stateSelector//''​ has any change|''//​ActiveZone//''​ \\ //''​AnalogInput''//​ \\ //''​AnalogInputsAll''//​ \\ //''​BinaryInput''//​ \\ //''​BinaryInputsAll''//​ \\ //''​BinaryOutput''//​ \\ //''​BinaryOutputsAll''//​ \\ //''​BrightnessLevel''//​ \\ //''​HumidityInput''//​ \\ //''​HumidityInputsAll''//​ \\ //''​HvacCoolerIsOn''//​ \\ //''​HvacFanIsOn''//​ \\ //''​HvacFanMode''//​ \\ //''​HvacFanModeIsAlwaysOn''//​ \\ //''​HvacFanModeIsAuto''//​ \\ //''​HvacHeaterIsOn''//​ \\ //''​HvacOperationModeIsAuto''//​ \\ //''​HvacOperationModeIsCool''//​ \\ //''​HvacOperationModeIsHeat''//​ \\ //''​HvacOperationModeIsOff''//​ \\ //''​HvacOperationModeIsProgramAuto''//​ \\ //''​HvacOperationModeIsProgramCool''//​ \\ //''​HvacOperationModeIsProgramHeat''//​ \\ //''​OnOffState''//​ \\ //''​SensorInput''//​ \\ //''​SensorInputsAll''//​ \\ //''​SetpointCool''//​ \\ //''​SetpointHeat''//​ \\ //''​TemperatureInput''//​ \\ //''​TemperatureInputsAll''//​ \\ //''​Zone''//​|
 +
 +
 +== State Selector Enumeration ==
 +
 +^  indigo.kStateSelector ​ ^^
 +^  Value  ^  Description ​ ^
 +|//''​ActiveZone''//​|monitor the sprinkler’s activeZone to become =, !=, or any change |
 +|//''​AnalogInput''//​|monitor (one of) the analog input(s) available on the device for =, !=, <, >, or any change - stateSelectorIndex is required to be in the range of available inputs|
 +|//''​AnalogInputsAll''//​|monitors all of the analog inputs available on the device for any change|
 +|//''​BinaryInput''//​|monitor (one of) the binary input(s) to become true, false, or any change - stateSelectorIndex is required to be in the range of available inputs|
 +|//''​BinaryInputsAll''//​|monitors all of the binary inputs available on the device for any change|
 +|//''​BinaryOutput''//​|monitor (one of) the binary output(s) to become true, false, or any change - stateSelectorIndex is required to be in the range of available outputs|
 +|//''​BinaryOutputsAll''//​|monitors all of the binary outputs available on the device for any change
 +|''//​BrightnessLevel//''​|monitor the brightness level of a device for =, !=, <, >, and any change|
 +|//''​HumidityInput''//​|monitor (one of) the humdity sensor(s) available on the device for =, !=, <, >, and any change ​ - stateSelectorIndex is required to be in the range of available inputs|
 +|//''​HumidityInputsAll''//​|monitors all of the humidity sensors available on the device for any change|
 +|//''​HvacCoolerIsOn''//​|monitor the thermostat for any time the air conditioning turns on, off, or has any change (coolIsOn is the current compressor state)|
 +|//''​HvacFanIsOn''//​|monitor the thermostat for any time the fan turns on, off, or has any change (fanIsOn is the current fan state)|
 +|//''​HvacFanMode''//​|monitor the fanMode of the thermostat for any change|
 +|//''​HvacFanModeIsAlwaysOn''//​|monitor the fanMode of the thermostat for a change to/​from ​ kFanMode.AlwaysOn|
 +|//''​HvacFanModeIsAuto''//​|monitor the fanMode of the thermostat for a change to/​from ​ kFanMode.AutoOn|
 +|//''​HvacHeaterIsOn''//​|monitor the thermostat for any time the heater turns on, off, or has any change (heatIsOn is the current heater state)|
 +|//''​HvacOperationMode''//​|monitor the hvacMode of the thermostat for any change|
 +|//''​HvacOperationModeIsAuto''//​|monitor the hvacMode of the thermostat for a change to/from kHvacMode.HeatCoolOn|
 +|//''​HvacOperationModeIsCool''//​|monitor the hvacMode of the thermostat for a change to/from kHvacMode.CoolOn|
 +|//''​HvacOperationModeIsHeat''//​|monitor the hvacMode of the thermostat for a change to/from kHvacMode.HeatOn|
 +|//''​HvacOperationModeIsOff''//​|monitor the hvacMode of the thermostat for a change to/from kHvacMode.Off|
 +|//''​HvacOperationModeIsProgramAuto''//​|monitor the hvacMode of the thermostat for a change to/from kHvacMode.ProgramAuto|
 +|//''​HvacOperationModeIsProgramCool''//​|monitor the hvacMode of the thermostat for a change to/from kHvacMode.ProgramCool|
 +|//''​HvacOperationModeIsProgramHeat''//​|monitor the hvacMode of the thermostat for a change to/from kHvacMode.ProgramHeat|
 +|//''​KeypadButtonLed''//​|FIXME|
 +|//''​OnOffState''//​|monitor the device for a change to/from on/off|
 +|//''​SensorInput''//​|monitor (one of) the sensor input(s) available on the device for =, !=, <, >, or any change ​ - stateSelectorIndex is required to be in the range of available inputs|
 +|//''​SensorInputsAll''//​|monitors all of the sensor inputs available on the device for any change|
 +|//''​SetpointCool''//​|monitor the cool setpoint of the thermostat for =, !=, <, >, or any change |
 +|//''​SetpointHeat''//​|monitor the heat setpoint of the thermostat for =, !=, <, >, or any change |
 +|//''​TemperatureInput''//​|monitor (one of) the temperature sensor(s) available on the device for =, !=, <, >, and any change - stateSelectorIndex is required to be in the range of available inputs|
 +|//''​TemperatureInputsAll''//​|monitors all of the temperature sensors available on the device for any change|
 +|//''​Zone''//​|monitor (one of) the binary output(s) to become true, false, or any change - stateSelectorIndex is required to be in the range of available outputs|
 +
 +==== Commands (indigo.devStateChange.*) ====
 +
 +=== Create ===
 +
 +Create a DeviceStateChange trigger. This method returns a **copy** of the newly created trigger.
 +
 +^  Command Syntax Examples ​ ^
 +|<​code>​indigo.devStateChange.create(name="​Trigger Name Here", ​
 +    description="​Description Here", ​
 +    folder=1234)</​code>​|
 +
 +^  Parameters ​ ^^^^
 +^  Parameter ​ ^  Required ​ ^  Type  ^  Description ​ ^
 +|''//​description//''​| ​ No  |  string ​ |the description of the trigger|
 +|//''​name''//​| ​ Yes  |  string ​ |the name of the trigger|
 +|''//​folder//''​| ​ No  |  integer ​ |id or instance of the folder in which to put the newly created trigger|
 +
 +==== Examples ====
 +
 +So, let’s look at a concrete example - a thermostat. A thermostat has several states which can be monitored, a couple of which may be lists. Specifically,​ a thermostat may have multiple temperature sensors and multiple humidity sensors. ​
 +
 +Here is an example of creating a device state changed trigger that will execute when the first temperature of thermostat id 738 (named "Main Thermostat"​) goes over 80 degrees in Python:
 +
 +FIXME add additional constructor args when they'​re done
 +
 +^  Python ​ ^  AppleScript ​ ^
 +|<​code>​theTrigger=indigo.devStateChange.create(name="​Temp exceeds 80 degrees"​)
 +
 +theTrigger.deviceId = 738
 +theTrigger.stateChangeType = indigo.kStateChange.BecomesGreaterThan
 +theTrigger.stateSelector = indigo.kStateSelector.TemperatureInput
 +theTrigger.stateSelectorIndex = 1
 +theTrigger.stateValue = 80
 +theTrigger.replaceOnServer()</​code>​|<​code>​set theTrigger to make new trigger action with properties {name:"​Temp exceeds 80 degrees"​}
 +set theTrigger'​s trigger type to deviceChanged
 +set theTrigger'​s device name to "Main Thermostat"​
 +set theTrigger'​s state change type to becomesGreaterThan
 +set theTrigger'​s state selector to "​TemperatureInput1"​
 +
 +set theTrigger'​s state value to 80
 +
 +
 +</​code>​|
 +
 +===== EmailReceivedTrigger =====
 +
 +The EmailReceivedTrigger object represents the email scanning feature in Indigo. You can match on any email received or based on the match fields - subject and/or from email address.
 +
 +==== Class Properties ====
 +^  //''​Property''// ​ ^  Writable ​ ^  Type  ^  Description ​ ^
 +|//''​emailFilter''//​| ​ [[#​email_filter_enumeration|kEmailFilter]] ​ |  Yes  |the type of email filter based on the ''//​kEmailFilter//''​ enumeration below|
 +|//''​emailFrom''//​| ​ string ​ |  Yes  |if ''//​emailFilter//''​ is ''//​MatchEmailFields//'',​ the value to match against the sender’s address|
 +|//''​emailSubject''//​| ​ string ​ |  Yes  |if ''//​emailFilter//''​ is ''//​MatchEmailFields//'',​ the value to match against the subject line|
 +
 +== Email Filter Enumeration ==
 +
 +^  indigo.kEmailFilter ​ ^^
 +^  Value  ^  Description ​ ^
 +|//''​AnyEmail''//​|when any email is received|
 +|//''​MatchEmailFields''//​|when email subject/​from fields match|
 +
 +==== Commands (indigo.emailRcvd.*) ====
 +
 +=== Create ===
 +
 +Create a EmailReceivedTrigger. This method returns a **copy** of the newly created trigger.
 +
 +^  Command Syntax Examples ​ ^
 +|<​code>​indigo.emailRcvd.create(name="​Trigger Name Here", ​
 +    description="​Description Here", ​
 +    folder=1234)</​code>​|
 +
 +^  Parameters ​ ^^^^
 +^  Parameter ​ ^  Required ​ ^  Type  ^  Description ​ ^
 +|''//​description//''​| ​ No  |  string ​ |the description of the trigger|
 +|//''​name''//​| ​ Yes  |  string ​ |the name of the trigger|
 +|''//​folder//''​| ​ No  |  integer ​ |id or instance of the folder in which to put the newly created trigger|
 +
 +==== Examples ====
 +
 +FIXME add additional constructor args when they'​re done
 +
 +^  Python ​ ^  AppleScript ​ ^
 +|<​code>​theTrigger=indigo.emailRcvd.create(name="​Emails from some@body.com"​)
 +
 +theTrigger.emailFilter = indigo.kEmailFilter.MatchEmailFields
 +theTrigger.emailFrom = "​some@body.com"​
 +theTrigger.replaceOnServer()</​code>​|<​code>​set theTrigger to make new trigger action with properties {name:"​Emails from some@body.com"​}
 +set theTrigger'​s trigger type to emailReceived
 +set theTrigger'​s email filter to matchEmailFields
 +set theTrigger'​s email from to "​some@body.com"​
 +
 +
 +</​code>​|
 +
 +===== InsteonCommandReceivedTrigger =====
 +
 +The InsteonCommandReceivedTrigger object will match incoming INSTEON command events. ​
 +
 +==== Class Properties ====
 +
 +^  Property ​ ^  Type  ^  Writable ​ ^  Description ​ ^
 +|//''​deviceId''//​| ​ integer ​ |  Yes  |the unique device id - only used if //''​commandSourceType''//​ is //''​DeviceId''//​|
 +|//''​command''//​| ​ [[#​insteon_command_enumeration|kInsteonCmd]] ​ |  Yes  |the command to watch for|
 +|//''​commandSourceType''//​| ​ [[#​trigger_device_source_type_enumeration|kDeviceSourceType]] ​ |  Yes  |the source type - for INSTEON only //''​DeviceId''//​ and //''​AnyDevice''//​ apply - and //''​deviceId''//​ above will only be used if set to //''​DeviceId''//​ |
 +|//''​buttonOrGroup''//​| ​ integer ​ |  Yes  |the button or group number from which the command is received - see [[#​About_Button_or_Group_Numbers_in_INSTEON_Events|About Button or Group Numbers]] below for details|
 +
 +=== About Button or Group Numbers in INSTEON Events ===
 +
 +Various INSTEON devices support features that are implemented via extra group identifiers. For instance, a KeypadLinc will broadcast each of the commands below from each button on it, and each KeypadLinc may have either 6 or 8 buttons depending on configuration. Other devices, like the Motion Sensor and the TriggerLinc will broadcast out group numbers based on other events (battery low, motion detected, dusk/dawn sensor, etc.). Check the [[https://​wiki.indigodomo.com/​|How-To Wiki]] for details about button and/or group numbers for the specific device type you’re interested in.
 +
 +== INSTEON Command Enumeration ==
 +
 +^  indigo.kInsteonCmd ​ ^^
 +^  Value  ^  Description ​ ^
 +|//''​AllBrighten''//​|when an all brighten command begins|
 +|//''​AllDim''//​|when an all dim command begins|
 +|//''​AllInstantOff''//​|when an all instant (fast) off is received|
 +|//''​AllInstantOn''//​|when an all instant (fast) on is received|
 +|//''​AllOff''//​|when an all off is received|
 +|//''​AllOn''//​|when an all on is received|
 +|//''​AnyCommand''//​|when any command is received|
 +|//''​Brighten''//​|when a brighten command begins|
 +|//''​Dim''//​|when a dim command begins|
 +|//''​InstantOff''//​|when an Instant (Fast) off is received in response to a double-tap|
 +|//''​InstantOn''//​|when an Instant (Fast) on is received in response to a double-tap|
 +|//''​Off''//​|when an off command is received|
 +|//''​On''//​|when an on command is received|
 +|//''​StatusChanged''//​|when a status change broadcast is received|
 +
 +== Trigger Device Source Type Enumeration ==
 +
 +^  indigo.kDeviceSourceType ​ ^^
 +^  Value  ^  Description ​ ^
 +|''//​NoDevice//''​|when the source uses no device or address (only used for X10 RF A/V remotes)|
 +|//''​Device''//​|when the source is an existing device, the ID is specified|
 +|//''​Address''//​|when the source is a raw X10 address|
 +|//''​AnyAddress''//​|when the source is any X10 address or INSTEON device|
 +
 +==== Commands (indigo.insteonCmdRcvd.*) ====
 +
 +=== Create ===
 +
 +Create a InsteonCommandReceivedTrigger. This method returns a **copy** of the newly created trigger.
 +
 +^  Command Syntax Examples ​ ^
 +|<​code>​indigo.insteonCmdRcvd.create(name="​Trigger Name Here", ​
 +    description="​Description Here", ​
 +    folder=1234)</​code>​|
 +
 +^  Parameters ​ ^^^^
 +^  Parameter ​ ^  Required ​ ^  Type  ^  Description ​ ^
 +|''//​description//''​| ​ No  |  string ​ |the description of the trigger|
 +|//''​name''//​| ​ Yes  |  string ​ |the name of the trigger|
 +|''//​folder//''​| ​ No  |  integer ​ |id or instance of the folder in which to put the newly created trigger|
 +
 +==== Examples ====
 +
 +FIXME add additional constructor args when they'​re done
 +
 +^  Python ​ ^  AppleScript ​ ^
 +|<​code>​theTrigger= indigo.insteonCmdRcvd.create(name="​KeypadLinc button 1 Any Change"​)
 +theTrigger.command = indigo.kInsteonCmd.AnyCommand
 +theTrigger.commandSourceType = indigo.kDeviceSourceType.Device
 +theTrigger.deviceId = 43829874
 +theTrigger.buttonOrGroup = 1
 +theTrigger.replaceOnServer()</​code>​|(Can'​t be created in AppleScript)|
 +===== InterfaceFailureTrigger =====
 +
 +The InterfaceFailureTrigger object represents the trigger that’s executed when an interface fails for some reason.
 +
 +==== Class Properties ====
 +
 +The InterfaceFailed trigger has no additional properties.
 +==== Commands (indigo.interfaceFail.*) ====
 +
 +=== Create ===
 +
 +Create a InterfaceFailureTrigger. This method returns a **copy** of the newly created trigger.
 +
 +^  Command Syntax Examples ​ ^
 +|<​code>​indigo.interfaceFail.create(name="​Trigger Name Here", ​
 +    description="​Description Here", ​
 +    folder=1234)</​code>​|
 +
 +^  Parameters ​ ^^^^
 +^  Parameter ​ ^  Required ​ ^  Type  ^  Description ​ ^
 +|''//​description//''​| ​ No  |  string ​ |the description of the trigger|
 +|//''​name''//​| ​ Yes  |  string ​ |the name of the trigger|
 +|''//​folder//''​| ​ No  |  integer ​ |id or instance of the folder in which to put the newly created trigger|
 +
 +==== Examples ====
 +
 +^  Python ​ ^  AppleScript ​ ^
 +|<​code>​theTrigger= indigo.interfaceFail.create(name="​Any Interface Failed"​)
 +
 +
 +</​code>​|<​code>​set theTrigger to make new trigger action with properties ¬
 +    {name:"​Any Interface Failed",​ trigger type:​interfaceFailure}</​code>​|
 +
 +    ​
 +===== InterfaceInitializedTrigger =====
 +
 +The InterfaceInitializedTrigger object represents the trigger that’s executed when an interface initializes successfully.
 +
 +==== Class Properties ====
 +
 +InterfaceInitializedTrigger has no additional properties.
 +==== Commands (indigo.interfaceInit.*) ====
 +
 +=== Create ===
 +
 +Create a InterfaceInitializedTrigger. This method returns a **copy** of the newly created trigger.
 +
 +^  Command Syntax Examples ​ ^
 +|<​code>​indigo.interfaceInit.create(name="​Trigger Name Here", ​
 +    description="​Description Here", ​
 +    folder=1234)</​code>​|
 +
 +^  Parameters ​ ^^^^
 +^  Parameter ​ ^  Required ​ ^  Type  ^  Description ​ ^
 +|''//​description//''​| ​ No  |  string ​ |the description of the trigger|
 +|//''​name''//​| ​ Yes  |  string ​ |the name of the trigger|
 +|''//​folder//''​| ​ No  |  integer ​ |id or instance of the folder in which to put the newly created trigger|
 +
 +==== Examples ==== 
 +
 +^  Python ​ ^  AppleScript ​ ^
 +|<​code>​theTrigger= indigo.interfaceInit.create(name="​Any Interface Initialized"​)
 +
 +
 +</​code>​|<​code>​set theTrigger to make new trigger action with properties ¬
 +    {name:"​Any Interface Initialized",​ trigger type:​interfaceInitialized}</​code>​|
 +
 +
 +===== PluginEventTrigger =====
 +
 +A plugin event is defined by a plugin.
 +
 +==== Class Properties ====
 +
 +^  Property ​ ^  Type  ^  Description ​ ^
 +|//''​pluginId''//​| ​ string ​ |the unique ID of the plugin, specified in the Info.plist for the plugin (or it’s documentation)|
 +|//''​pluginTypeId''//​| ​ string ​ |the id specified in the Events.xml (or it’s documentation)|
 +
 +==== Commands (indigo.pluginEvent.*) ====
 +
 +=== Create ===
 +
 +Create a trigger. You can create triggers using this method of any type except for events that are defined by your plugin (that class, PluginEventTrigger,​ has it's own create() method). This method returns a **copy** of the newly created trigger. Once a trigger of this type is created, the properties can change (via the [[#​properties|pluginProps in the Trigger base class]]), but nothing else can be changed.
 +
 +^  Command Syntax Examples ​ ^
 +|<​code>​indigo.pluginEvent.create(name="​Trigger Name Here", ​
 +    description="​Description Here", ​
 +    folder=1234),​
 +    pluginId="​com.mycompany.myplugin",​
 +    pluginTypeId="​myEvent",​
 +    props={"​propA":"​value","​propB":"​value"​}</​code>​|
 +
 +^  Parameters ​ ^^^^
 +^  Parameter ​ ^  Required ​ ^  Type  ^  Description ​ ^
 +|''//​description//''​| ​ No  |  string ​ |the description of the trigger|
 +|//''​name''//​| ​ Yes  |  string ​ |the name of the trigger|
 +|''//​folder//''​| ​ No  |  integer ​ |id or instance of the folder in which to put the newly created trigger|
 +|''//​pluginId//''​| ​ No  |  string ​ |the plugin id of the plugin that owns the device you're creating - if it's not present it defaults to your plugin'​s id|
 +|''//​pluginTypeId//''​| ​ Yes  |  string ​ |this is the id of the <​Event>​ as specified in the Events.xml or in the documentation for the plugin|
 +|''//​props//''​| ​ No  |  dictionary ​ |this is the properties for the trigger - they will be inserted in to the pluginId'​s property space as supplied above. If you are creating a trigger of a type defined in a different plugin, it's that plugin'​s id and properties.|
 +
 +==== Examples ==== 
 +
 +AppleScript can't create objects of this type. See the Command Syntax above for an example. See [[#​firing_plugin_defined_triggers|Firing Plugin Defined Triggers]] above for details on how your plugin should watch and fire triggers based on events defined in your Events.xml.
 +===== PowerFailureTrigger =====
 +
 +The PowerFailureTrigger object represents a trigger that’s executed when an interface loses power (if applicable). Note - not all interfaces can detect a power failure - usually only those interfaces that are plugged directly into an electrical outlet.
 +
 +==== Class Properties ====
 +
 +PowerFailureTrigger has no additional properties.
 +
 +==== Commands (indigo.powerFailure.*) ====
 +
 +=== Create ===
 +
 +Create a PowerFailureTrigger. This method returns a **copy** of the newly created trigger.
 +
 +^  Command Syntax Examples ​ ^
 +|<​code>​indigo.powerFailure.create(name="​Trigger Name Here", ​
 +    description="​Description Here", ​
 +    folder=1234)</​code>​|
 +
 +^  Parameters ​ ^^^^
 +^  Parameter ​ ^  Required ​ ^  Type  ^  Description ​ ^
 +|''//​description//''​| ​ No  |  string ​ |the description of the trigger|
 +|//''​name''//​| ​ Yes  |  string ​ |the name of the trigger|
 +|''//​folder//''​| ​ No  |  integer ​ |id or instance of the folder in which to put the newly created trigger|
 +
 +==== Examples ====
 +
 +^  Python ​ ^  AppleScript ​ ^
 +|<​code>​theTrigger= indigo.powerFailure.create(name="​Any Interface Detected Power Failure"​)
 +
 +
 +</​code>​|<​code>​set theTrigger to make new trigger action with properties ¬
 +    {name:"​Any Interface Detected Power Failure",​ trigger type:​powerFailure}</​code>​|
 +
 +===== ServerStartupTrigger =====
 +
 +The ServerStartupTrigger class represents a trigger that’s executed when the IndigoServer process starts up. This is a special event in that it adds no additional parameters beyond what it inherits from [[#​trigger|Trigger]].
 +
 +==== Commands (indigo.serverStartup.*) ====
 +
 +=== Create ===
 +
 +Create a ServerStartupTrigger trigger. This method returns a **copy** of the newly created trigger.
 +
 +^  Command Syntax Examples ​ ^
 +|<​code>​indigo.serverStartup.create(name="​Trigger Name Here", ​
 +    description="​Description Here", ​
 +    folder=1234)</​code>​|
 +
 +^  Parameters ​ ^^^^
 +^  Parameter ​ ^  Required ​ ^  Type  ^  Description ​ ^
 +|''//​description//''​| ​ No  |  string ​ |the description of the trigger|
 +|//''​name''//​| ​ Yes  |  string ​ |the name of the trigger|
 +|''//​folder//''​| ​ No  |  integer ​ |id or instance of the folder in which to put the newly created trigger|
 +
 +==== Examples ====
 +
 +^  Python ​ ^  AppleScript ​ ^
 +|<​code>​theTrigger= indigo.serverStartup.create(name="​Startup"​)
 +
 +
 +</​code>​|<​code>​set theTrigger to make new trigger action with properties ¬
 +    {name:"​Startup",​ trigger type:​startup}</​code>​|
 +
 +===== X10CommandReceivedTrigger =====
 +
 +The X10CommandReceivedTrigger object will match incoming X10 command events.
 +
 +==== Class Properties ====
 +
 +^  Property ​ ^  Type  ^  Description ​ ^
 +|//''​address''//​| ​ string ​ |if commandSourceType = Address, the full X10 address to listen for or just the house code if command is All* or AnyCommand|
 +|//''​deviceId''//​| ​ integer ​ |if commandSourceType = Device, the unique device id|
 +|//''​command''//​| ​ kX10Cmd ​ |the X10 command to watch for|
 +|//''​commandSourceType''//​| ​ kDeviceSourceType ​ |the type of source specified for this trigger|
 +|//''​AvButton''//​| ​ kX10AvButton ​ |if command = AvButtonPressed,​ the A/V button to monitor|
 +
 +== X10 Command Enumeration ==
 +
 +^  indigo.kX10Cmd ​ ^^
 +^  Value  ^  Description ​ ^
 +|//''​AllOff''//​|when an all off is received|
 +|//''​AllLightsOff''//​|when an all lights off is received|
 +|//''​AllLightsOn''//​|when an all lights on is received|
 +|//''​AvButtonPressed''//​|when an A/V button press is received|
 +|//''​AnyCommand''//​|when any command is received|
 +|//''​Brighten''//​|when a brighten command begins|
 +|//''​Dim''//​|when a dim command begins|
 +|//''​ExtendedData''//​|when an extended data X10 command is received|
 +|//''​Off''//​|when an off command is received|
 +|//''​On''//​|when an on command is received|
 +|//''​PresetDim''//​|when a preset dim command is received|
 +|//''​StatusOffResponse''//​|when a status off response is received|
 +|//''​StatusOnResponse''//​|when a status on response is received|
 +
 +== X10 A/V Button Enumeration ==
 +
 +^  indigo.kX10AvButton ​ ^^
 +^  Value  ^  Value  ^
 +|  ''//​0//'' ​ |  ''//​Left//'' ​ |
 +|  ''//​1//'' ​ |  ''//​Menu//'' ​ |
 +|  ''//​2//'' ​ |  ''//​Mute//'' ​ |
 +|  ''//​3//'' ​ |  ''//​Pause//'' ​ |
 +|  ''//​4//'' ​ |  ''//​PC//'' ​ |
 +|  ''//​5//'' ​ |  ''//​Play//'' ​ |
 +|  ''//​6//'' ​ |  ''//​Power//'' ​ |
 +|  ''//​7//'' ​ |  ''//​Recall//'' ​ |
 +|  ''//​8//'' ​ |  ''//​Record//'' ​ |
 +|  ''//​9//'' ​ |  ''//​Return//'' ​ |
 +|  //''​AB''// ​ |  ''//​Rewind//'' ​ |
 +|  //''​ChannelDown''// ​ |  ''//​Right//'' ​ |
 +|  //''​ChannelUp''// ​ |  ''//​Stop//'' ​ |
 +|  //''​Display''// ​ |  ''//​Title//'' ​ |
 +|  //''​Down''// ​ |  ''//​Up//'' ​ |
 +|  //''​Enter''// ​ |  ''//​VolumeDown//'' ​ |
 +|  //''​Exit''// ​ |  ''//​VolumeUp//'' ​ |
 +|  //''​Forward''// ​ |
 +
 +==== Commands (indigo.x10CmdRcvd.*) ====
 +
 +=== Create ===
 +
 +Create an X10CommandReceivedTrigger. This method returns a **copy** of the newly created trigger.
 +
 +^  Command Syntax Examples ​ ^
 +|<​code>​indigo.x10CmdRcvd.create(name="​Trigger Name Here", ​
 +    description="​Description Here", ​
 +    folder=1234)</​code>​|
 +
 +^  Parameters ​ ^^^^
 +^  Parameter ​ ^  Required ​ ^  Type  ^  Description ​ ^
 +|''//​description//''​| ​ No  |  string ​ |the description of the trigger|
 +|//''​name''//​| ​ Yes  |  string ​ |the name of the trigger|
 +|''//​folder//''​| ​ No  |  integer ​ |id or instance of the folder in which to put the newly created trigger|
 +
 +==== Examples ====
 +
 +AppleScript can't create this kind of trigger. Here's a Python example:
 +
 +<​code>​myTrigger=indigo.x10CmdRcvd.create(name="​Received any command from F7")
 +myTrigger.command = indigo.kX10Cmd.AnyCommand
 +myTrigger.commandSourceType = indigo.kDeviceSourceType.Address
 +myTrigger.address = "​F7"​
 +myTrigger.replaceOnServer()</​code>​
 +===== VariableChangeTrigger =====
 +
 +The VariableChangeTrigger object will match variable changes.
 +
 +==== Class Properties ====
 +
 +^  Property ​ ^  Type  ^  Description ​ ^
 +|//''​variableChangeType''//​| ​ [[#​variable_change_type_enumeration|kVarChange]] ​ |the type of variable change to monitor|
 +|//''​variableId''//​| ​ integer ​ |the unique variable id|
 +|//''​variableValue''//​| ​ string ​ |the value to compare against the variable’s value if ''//​variableChangeType//''​ is =, !=, >, <|
 +
 +== Variable Change Type Enumeration ==
 +
 +^  indigo.kVarChange ​ ^^
 +^  Value  ^  Description ​ ^
 +|//''​BecomesEqual''//​|variable value becomes equal to|
 +|//''​BecomesFalse''//​|variable value becomes false|
 +|//''​BecomesGreaterThan''//​|variable value becomes greater than|
 +|//''​BecomesLessThan''//​|variable value becomes less than|
 +|//''​BecomesNotEqual''//​|variable value becomes not equal to|
 +|//''​BecomesTrue''//​|variable value becomes true|
 +|//''​Changes''//​|variable value has any change|
 +
 +==== Commands (indigo.varChange.*) ====
 +
 +=== Create ===
 +
 +Create an VariableChangeEvent. This method returns a **copy** of the newly created trigger.
 +
 +^  Command Syntax Examples ​ ^
 +|<​code>​indigo.varChange.create(name="​Trigger Name Here", ​
 +    description="​Description Here", ​
 +    folder=1234)</​code>​|
 +
 +^  Parameters ​ ^^^^
 +^  Parameter ​ ^  Required ​ ^  Type  ^  Description ​ ^
 +|''//​description//''​| ​ No  |  string ​ |the description of the trigger|
 +|//''​name''//​| ​ Yes  |  string ​ |the name of the trigger|
 +|''//​folder//''​| ​ No  |  integer ​ |id or instance of the folder in which to put the newly created trigger|
 +
 +==== Examples ====
 +
 +
 +FIXME add additional constructor args when they'​re done
 +
 +^  Python ​ ^  AppleScript ​ ^
 +|<​code>​theTrigger=indigo.emailRcvd.create(name="​Var Changed to True")
 +
 +theTrigger.variableChangeType = indigo.kVarChange.BecomesEqual
 +theTrigger.variableId = 9283749872
 +theTrigger.variableValue = "​True"​
 +theTrigger.replaceOnServer()</​code>​|<​code>​set theTrigger to make new trigger action with properties {name:"​Var Changed to True"}
 +set theTrigger'​s trigger type to variableChanged
 +set theTrigger'​s variable change type to varBecomesEqual
 +set theTrigger'​s variable name to "​SomeVarWhoseIdIs9283749872"​
 +set theTrigger'​s variable value to "​True"​
 +
 +
 +</​code>​|
indigo_5_documentation/trigger_class.txt · Last modified: 2019/01/25 22:53 (external edit)
 

© Perceptive Automation, LLC. · Privacy