Command Triggers

To execute a command automatically, set the template of the command and the condition in the trigger. See the below examples.

Registering One-Time Schedule Triggers

We will show how to register a trigger to turn on an air conditioner (with the preset temperature and fan speed set to 25 degrees and 5, respectively) 1 hour from now.

// Create a command.
var actions = [Dictionary<String, AnyObject>]()
let action1: Dictionary<String, AnyObject> = ["turnPower": ["power": true]]
let action2: Dictionary<String, AnyObject> = ["setPresetTemperature": ["presetTemperature": 25]]
let action3: Dictionary<String, AnyObject> = ["setFanSpeed": ["fanSpeed": 5]]
actions.append(action1)
actions.append(action2)
actions.append(action3)

// Create a predicate.
// Execute the command in an hour.
let scheduleAt = NSDate(timeIntervalSinceNow: 60*60)
let predicate = ScheduleOncePredicate(scheduleAt: scheduleAt)

// Send a trigger.
api.postNewTrigger("AirConditioner-Demo", schemaVersion: 1, actions: actions, predicate: predicate, completionHandler: { (trigger: Trigger?, error: ThingIFError?) -> Void in
  if error != nil {
    // Handle the error.
    return
  }
})

This is what is happening in the sample code:

  • Create the command to be executed by the trigger as [Dictionary<String, AnyObject>]. Here, we are setting three actions in sequence. How the command is set is the same as that in the code of Executing Commands.

  • Set the execution time in scheduleAt and use it as the argument of the ScheduleOncePredicate.

  • Finally, execute the postNewTrigger method to register the trigger.

The callback method will be called when Thing Interaction Framework accepts the trigger.

Registering Recurring Schedule Triggers

We will show how to register a trigger to turn on an air conditioner (with the preset temperature and fan speed set to 25 degrees and 5, respectively) at 9:00 a.m. every day.

// Create a command.
var actions = [Dictionary<String, AnyObject>]()
let action1: Dictionary<String, AnyObject> = ["turnPower": ["power": true]]
let action2: Dictionary<String, AnyObject> = ["setPresetTemperature": ["presetTemperature": 25]]
let action3: Dictionary<String, AnyObject> = ["setFanSpeed": ["fanSpeed": 5]]
actions.append(action1)
actions.append(action2)
actions.append(action3)

// Create a predicate.
// Execute the command at 9:00 a.m. every day.
let predicate = SchedulePredicate(schedule: "0 9 * * *")

// Send a trigger.
api.postNewTrigger("AirConditioner-Demo", schemaVersion: 1, actions: actions, predicate: predicate, completionHandler: { (trigger: Trigger?, error: ThingIFError?) -> Void in
  if error != nil {
    // Handle the error.
    return
  }
})

The basic steps are the same as the case of a one-time schedule trigger. The only difference is how the execution condition is initialized.

  • Set the execution time in schedule and use it as the argument of the SchedulePredicate. See Recurring Schedule to learn how to set the time.

Registering State Condition Triggers

The next example shows how to register a trigger with a simple condition. We will show how to register a trigger to turn on an air conditioner (with the preset temperature and fan speed set to 25 degrees and 5, respectively) when "the room temperature goes over 30 degrees".

// Create a command.
var actions = [Dictionary<String, AnyObject>]()
let action1: Dictionary<String, AnyObject> = ["turnPower": ["power": true]]
let action2: Dictionary<String, AnyObject> = ["setPresetTemperature": ["presetTemperature": 25]]
let action3: Dictionary<String, AnyObject> = ["setFanSpeed": ["fanSpeed": 5]]
actions.append(action1)
actions.append(action2)
actions.append(action3)

// Create a predicate.
// Execute the command when the temperature is greater than or equal to 30 deg C.
let condition = Condition(clause:RangeClause(field: "currentTemperature", lowerLimit: 30, lowerIncluded: true))
let predicate = StatePredicate(condition: condition, triggersWhen: TriggersWhen.CONDITION_FALSE_TO_TRUE)

// Send a trigger.
api.postNewTrigger("AirConditioner-Demo", schemaVersion: 1, actions: actions, predicate: predicate, completionHandler: { (trigger: Trigger?, error: ThingIFError?) -> Void in
  if error != nil {
    // Handle the error.
    return
  }
})

The basic steps are the same as the case of schedule triggers. The only difference is how the execution condition is initialized.

  • Create a trigger condition. First, set the comparison condition in a Condition. In this example, we are creating the condition that will become true when currentTemperature defined in State is greater than or equal to 30 degrees.
  • Create a StatePredicate to finalize the trigger condition. In this example, we are specifying CONDITION_FALSE_TO_TRUE because we want to execute the command when the room temperature goes up from below 30 degrees to above 30 degrees.

Setting a Trigger with Multiple Conditions

The next example shows how to concatenate conditions with AND. In this example, we will set a trigger to set the fan speed to 10 when "the power is on" and "the room humidity is above 80".

// Create a command.
let actions: [Dictionary<String, AnyObject>] = [["setFanSpeed": ["fanSpeed": 10]]]

// Create a predicate.
// Execute the command when the power is on and the humidity is greater than 80%.
let condition = Condition(clause:
            AndClause(clauses:EqualsClause(field: "power", boolValue: true),
                              RangeClause(field: "currentHumidity", lowerLimitInt: 80, lowerIncluded: false)))
let predicate = StatePredicate(condition: condition, triggersWhen: TriggersWhen.CONDITION_FALSE_TO_TRUE)

// Send a trigger.
api.postNewTrigger("AirConditioner-Demo", schemaVersion: 1, actions: actions, predicate: predicate, completionHandler: { (trigger: Trigger?, error: ThingIFError?) -> Void in
  if error != nil {
    // Handle the error.
    return
  }
})

The basic steps are the same as the case of a single condition trigger. The only difference is how a Condition is initialized. In this example, we first create two conditions "power is equal to true" and "currnetHumidity is greater than 80", concatenate them with an And, and then set the concatenated condition as the comparison condition.

Registering Advanced Triggers

You can register advanced triggers as below by specifying detailed information.

  • A trigger which sends a command to a different thing

    You can register a trigger that sends a command to a different thing when a state condition is met on the thing to which you register the trigger.

    For example, if you manage a thermometer and an air conditioner as separate things, you can register a trigger to "turn on the air conditioner when the thermometer rises to a certain temperature".

  • A trigger with details of the trigger and the command in it

    You can set the title, description, and metadata of the trigger and the command in it.

// Create a command.
var actions = [Dictionary<String, AnyObject>]()
let action1: Dictionary<String, AnyObject> = ["turnPower": ["power": true]]
let action2: Dictionary<String, AnyObject> = ["setPresetTemperature": ["presetTemperature": 25]]
let action3: Dictionary<String, AnyObject> = ["setFanSpeed": ["fanSpeed": 5]]
actions.append(action1)
actions.append(action2)
actions.append(action3)

// Get the target thing that receives the command.
let target = api2.target
let targetID = target.getTypedID()

// Create a command form from detailed information.
let metadataCommand: Dictionary<String, AnyObject> = ["iconIndex":3, "issuer":"trigger"]
let form = TriggeredCommandForm(schemaName: "AirConditioner-Demo", schemaVersion: 1, actions: actions, targetID: targetID, title: "Power on", commandDescription: "Power on and set to 25 deg C", metadata: metadataCommand)

// Create a predicate.
let condition = Condition(clause:RangeClause(field: "currentTemperature", lowerLimit: 30, lowerIncluded: true))
let predicate = StatePredicate(condition: condition, triggersWhen: TriggersWhen.CONDITION_FALSE_TO_TRUE)

// Create trigger options from detailed information.
let metadataTrigger: Dictionary<String, AnyObject> = ["createdBy":"Alice"]
let options = TriggerOptions(title: "Power on", triggerDescription: "Power on when the temperature goes over 30 deg C", metadata: metadataTrigger)

// Send a trigger.
api.postNewTrigger(form: form, predicate: predicate, options: options, completionHandler: { (trigger: Trigger?, error: ThingIFError?) -> Void in
  if error != nil {
    // Handle the error.
    return
  }
})

The following processes are executed in the code:

  • Specify actions to be executed when the condition is met in actions.

  • Specify the command details in a TriggeredCommandForm.

    • Specify the thing to which the trigger sends the command with targetID.
      This sample code assumes that the thermometer and the air conditioner are managed with the ThingIFAPI instances, api and api2, respectively. When the state of api (thermometer) meets the trigger condition, the trigger sends a command which turns on the air conditioner to target obtained from api2 (air conditioner).
      You need to have instantiated and onboarded api and api2 with the same owner.
      Note that the command will be sent to the thing set in the ThingIFAPI instance which is specified to call the postNewTrigger method if you ommit targetID.
    • You can specify the command details with the title, description, and metadata.
      You can freely use these fields according to your mobile app specification as explained in Command Details. See Command Details also for limits such as the maximum length of each field.
  • Create the execution condition as a StatePredicate.

  • Specify the trigger details with a TriggerOptions. You can set information for your mobile app as you can for commands. The same limits such as the maximum length apply to triggers and commands.

  • Finally, register the new trigger by calling the postNewTrigger method with the TriggeredCommandForm, StatePredicate, and TriggerOptions which you created until now.