コマンドを実行するトリガー
コマンドを自動実行する場合、実行するコマンドのテンプレートと実行条件をトリガーに設定します。以下に例を示します。
時間条件(単発)のトリガーの登録
単発の時間条件を持つトリガーとして、「今から 1 時間後に、エアコンをオンにする(設定温度 25 度、ファンスピード 5)」というトリガーを登録する例を以下に示します。
// 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
}
})
ここでは以下の処理が行われています。
[Dictionary<String, AnyObject>]
に、トリガーによって実行されるコマンドを作成します。ここでは、3 つのアクションを順番に設定しています。設定方法は コマンドの実行 のコードと同じです。scheduleAt
にトリガーの実行時間を設定し、ScheduleOncePredicate
の引数とします。最終的に、
postNewTrigger
メソッドでトリガーを登録します。
Thing Interaction Framework がトリガーを受け付けた段階でコールバックメソッドが呼び出されます。
時間条件(繰り返し)のトリガーの登録
繰り返しの時間条件を持つトリガーとして、「毎日午前 9 時に、エアコンをオンにする(設定温度 25 度、ファンスピード 5)」というトリガーを登録する例を以下に示します。
// 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
}
})
基本的な流れは、単発の時間条件の場合と同じですが、トリガーの実行条件の初期化方法が異なります。
schedule
にトリガーの実行時間を設定し、SchedulePredicate
の引数とします。設定方法については、時間条件(繰り返し) を参照してください。
ステート条件のトリガーの登録
単純なステート条件を持つトリガーとして、「室温が 30 度以上の時、エアコンをオンにする(設定温度 25 度、ファンスピード 5)」というトリガーを登録する例を以下に示します。
// 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
}
})
基本的な流れは、時間条件の場合と同じですが、トリガーの実行条件の初期化方法が異なります。
- トリガーの条件を作成します。まず、
Condition
に比較条件を設定します。ここでは、ステート で登録しているcurrentTemperature
が 30 以上の場合に true になる条件を作成しています。 - 次に、
StatePredicate
を作成します。StatePredicate
が最終的にトリガーに登録する条件です。コマンドは、30 度未満の状態から 30 度以上になったときに実行したいため、CONDITION_FALSE_TO_TRUE
を指定します。
複数のステート条件での登録例
ステート条件を AND で結合する例を以下に示します。この例では、「電源がオン」かつ「湿度が 80 より大きい」場合に「ファンスピードを 10 に設定する」というトリガーを登録します。
// 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
}
})
基本的な流れは、単一のステート条件の場合と同じですが、Condition
の初期化方法が異なります。ここでは、「power
が true に等しい」という条件と、「currentHumidity
が 80 より大きい」という 2 つの条件を作成し、それを And
で結合したものを比較条件として設定しています。
詳細情報を指定したトリガーの登録例
トリガーを設定する際、詳細情報を指定することで、以下のようなトリガーを登録することができます。
他の Thing にコマンドを送信
ある Thing でステート条件が満たされたとき、別の Thing にコマンドを送信するようなトリガーを登録できます。
例えば、温度計デバイスとエアコンが別の Thing として管理されているとき、「温度計デバイスが一定の温度以上になったとき、エアコンの電源を入れる」というようなトリガーを実現できます。
コマンドやトリガーの詳細情報を設定
コマンドとトリガーのそれぞれに対して、タイトル、詳細な説明文、JSON 形式で表現された任意のメタ情報を設定できます。
// 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
}
})
ここでは、次の処理を行っています。
条件が満たされた場合に実行されるアクションを
actions
に用意します。実行するコマンドの詳細を
TriggeredCommandForm
に設定します。targetID
でコマンドの送信先の Thing を指定します。
このサンプルコードでは、ThingIFAPI インスタンスのapi
とapi2
によって、それぞれ温度計デバイスとエアコンの Thing が管理されているものとします。api
(温度計)のステートが指定条件を満たした場合、api2
(エアコン)から取得したtarget
に対してエアコンの電源を入れるコマンドを実行します。api
とapi2
は、それぞれでインスタンス生成や初期登録処理が実行されており、同一のオーナーであることが必要です。
なお、targetID
を省略した場合はpostNewTrigger
を実行した ThingIFAPI に設定されている Thing にコマンドを送信します。title
、commandDescription
、metadata
によって詳細情報を設定できます。
これらは コマンドの詳細情報 に示すとおり、アプリケーションの仕様に合わせて自由に利用できます。最大長などの制限値についても コマンドの詳細情報 をご覧ください。
実行する条件を
StatePredicate
として作成します。トリガーに対する詳細情報を
TriggerOptions
に設定します。コマンドと同様、アプリケーション独自の情報を設定できます。最大長などの制限値はコマンドに対する詳細情報と同じです。最後に、作成した
TriggeredCommandForm
、StatePredicate
、TriggerOptions
をpostNewTrigger
メソッドに指定して、新しいトリガーを登録します。