Automation DSL を使用すると、DSL ガイド - Android の基本的な自動化で説明した自動化よりも複雑な自動化を作成できます。
複数のアクションを含む順次
1 つの自動化で複数の処理を行うことができます。たとえば、単一の action ノードの代わりに、複数の action ノードを順番に実行できます。
automation {
sequential {
starter<_>(...)
condition {...}
action {...}
action {...}
action {...}
}
}
複数の並列アクションを含むシーケンシャル
複数の action ノードを parallel ノードに配置すると、アクションが同時に実行されます。
automation {
sequential {
starter<_>(...)
condition {...}
parallel {
action {...}
action {...}
action {...}
}
}
}
parallel ノードの後に sequential ノードに action ノードがある場合、parallel ノード内のすべてのノードの実行が完了するまで実行を待機します。
条件付き実行
デフォルトでは、自動化はノードを順次または並行して実行します。実行時の条件に基づいて異なるアクションやパスを実行する条件付き分岐ロジックが必要な場合は、条件付き制御フロー DSL ブロック(ifThen、elseIf、orElse)を使用して構築された if-then-else ステートメントを使用します。
標準の condition ノードは自動化全体をゲートしますが(条件が false と評価されると、自動化はすぐに実行を終了します)、ifThen ブロックを使用すると、制御フローを分岐できます。
conditionノード: 式がfalseの場合、自動化全体(または現在の実行パス)の実行を停止します。ifThen/elseIf/orElse: 条件を順番に評価します。条件がfalseの場合、実行は次のelseIfブランチ、orElseフォールバック ブランチにフォールスルーするか、条件が満たされない場合は自動化の後続ノードに進みます。
条件に基づいてアクションを実行する
ifThen ブロックは条件式を評価します。式が true と評価された場合、ブロック内にネストされた DSL アクションまたはノードが実行されます。false と評価された場合、アクションはスキップされ、自動化はシーケンシャル フローの後続のノードに進みます。
自動化の後続ノードをブロックまたは終了せずに、条件付きでアクションを実行する場合にのみ、スタンドアロンの ifThen ブロックを使用できます。
// When a door opens, turn on the light only if it is off,
// and always broadcast an announcement.
automation {
sequential {
val contactState = starter<_>(
contactSensor,
ContactSensorDevice,
BooleanState,
)
val lightState = stateReader<_>(
light,
DimmableLightDevice,
OnOff,
)
condition {
// Door opened (contact sensor open)
expression = contactState.stateValue equals false
}
// Conditionally turn on the light if it's off
ifThen(lightState.onOff equals false) {
action(light, DimmableLightDevice) { command(OnOff.on()) }
}
// Continue executing subsequent actions in the sequential flow
action(structure) {
command(AssistantBroadcast.broadcast("The door was opened."))
}
}
}
条件に基づいて異なるアクションを実行する
条件が true の場合に一連のアクションを実行し、false の場合に別の一連のアクションを実行するには、ifThen(...) { ... } の後にオプションの .orElse { ... } ブロックを連結します。
// When the door is unlocked, turn on the entryway light if it is off;
// otherwise, broadcast a welcome message.
automation {
sequential {
val doorLockEvent = starter<_>(
doorLock,
DoorLockDevice,
LockOperationEvent,
)
val lightState = stateReader<_>(
light,
DimmableLightDevice,
OnOff,
)
condition {
expression =
doorLockEvent.lockOperationType equals LockOperationTypeEnum.Unlock
}
ifThen(lightState.onOff equals false) {
action(light, DimmableLightDevice) { command(OnOff.on()) }
}.orElse {
action(structure) {
command(AssistantBroadcast.broadcast("Welcome home!"))
}
}
}
}
複数の条件を順番に連結する
1 つ以上のオプションの .elseIf(...) { ... } ブロックを連結して、複数の条件を順番に評価できます。条件が true と評価される最初の分岐が実行され、残りのすべての分岐はスキップされます。条件のいずれも true と評価されない場合、オプションの .orElse { ... } ブロックが実行されます(指定されている場合)。
// Adjust climate controls based on room temperature changes.
automation {
sequential {
val tempStarter = starter<_>(
tempSensor,
TemperatureSensorDevice,
TemperatureMeasurement,
)
// If temperature is high (>= 28°C / 2800 mC), switch thermostat to Cool mode
ifThen(tempStarter.measuredValue greaterThanOrEquals 2800) {
action(thermostat, ThermostatDevice) {
command(
SimplifiedThermostat.setSystemMode(
SimplifiedThermostatSystemModeEnum.Cool
)
)
}
}.elseIf(tempStarter.measuredValue lessThan 1800) {
// If temperature is low (< 18°C / 1800 mC), switch to Heat mode
action(thermostat, ThermostatDevice) {
command(
SimplifiedThermostat.setSystemMode(
SimplifiedThermostatSystemModeEnum.Heat
)
)
}
}.orElse {
// Otherwise, turn on the fan
action(fan, FanDevice) {
command(OnOff.on())
}
}
}
}
ネストされた条件付きフロー
条件ブロックは、他の ifThen、elseIf、orElse ブロック内にネストしたり、parallel、delayFor、stateReader ノードと組み合わせたりできます。
ifThen、elseIf、orElse ブロックは、コンテンツを順次フローとして実行します。action、stateReader、parallel、delayFor、ネストされた ifThen ブロックなど、任意のシーケンシャル ノードを各ブランチ内に配置できます。
処理の遅れ
delayFor キーワードを使用すると、自動化に一時停止を導入できます。このキーワードは、実行を再開するまでの待機時間を表す java.time.Duration 引数を取ります。一時停止の期間は、最短で 5 秒、最長で 24 時間です。
たとえば、ライトを 5 秒間隔で 4 回切り替えるには:
sequential {
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
delayFor(Duration.ofSeconds(5))
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
delayFor(Duration.ofSeconds(5))
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
delayFor(Duration.ofSeconds(5))
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
}
delayForトリガー抑制
トリガー抑制は、最初のトリガー イベントの後に指定した期間、自動化が starter を無視できるようにする機能です。たとえば、自動化にモーション検知(機能)によってトリガーされる starter があり、トリガー抑制期間を 5 分に指定した場合、starter がトリガーされると、次の 5 分間はトリガーされません。これにより、自動化が何度も繰り返しトリガーされるのを防ぐことができます。
トリガー抑制を自動化に適用するには、suppressFor キーワードと、後続のトリガーに応答するまでの待機時間を表す java.time.Duration 引数を使用します。抑制期間は、最短で 5 秒、最長で 24 時間です。
automation {
sequential {
val starterNode = starter<_>(device, OccupancySensor, MotionDetection)
suppressFor(Duration.ofMinutes(30))
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
}
トリガー抑制は、suppressFor の前にある自動化のすべての starters に影響します。
実行数を制限する
自動化の実行回数を制限できます。
たとえば、1 日中外出している間に掃除機をかける 1 回限りの自動化を設定できます。
これを行うには、自動化の maxExecutionCount メタデータ フィールドを設定します。次の例は、1 回だけ実行できる自動化です。
automation { // The automation can only be executed once. maxExecutionCount = 1 // When the door lock state changes sequential { val doorLockEvent = starter<_>(doorLock, DoorLockDevice, LockOperationEvent) // if the door is unlocked condition() { expression = (doorLockEvent.lockOperationType equals LockOperationTypeEnum.Unlock) } // turn the light on action(light, DimmableLightDevice) { command(OnOff.on()) } } }
自動化は、最後の実行が完了して maxExecutionCount に達するとすぐに削除されます。自動化の履歴エントリは、automation_id を含め、Google Home app (GHA) [アクティビティ] タブに残ります。
アクションで特性属性を設定する
トレイト属性の値を設定するには:
actionノード内にupdateノードを作成し、関連するトレイトをupdateノードの引数として含めます。action(deviceReference, deviceType) { update(trait) { } }updateノード内で、変更する属性ごとにミューテータ関数を使用し、新しい値を渡します。ミューテータ関数の名前を形成するには:- 属性名を大文字にする
- 接頭辞として
setという単語を付けます。
defaultMoveRateという属性を更新するには、setDefaultMoveRateというミューテータ関数を使用します。
update ノードには複数のミューテータ関数を設定できます。次の例では、2 つの属性が更新されています。
action(device, Fan) {
update(FanControl) {
setPercentSetting(50u)
setRockSetting(FanControlCluster.RockBitmap.rockUpDown)
}
}