iOS DSL ガイド

以下のガイドでは、さまざまな Automation DSL ノードを使用して自動化を構築する方法について説明します。

すべての自動化 DSL は、1 つの automation ノード内に配置されます。automation ノードは、外部の Swift 言語コンテキストと埋め込み DSL コンテキストの境界を形成します。

順次フロー

シーケンシャル フローは、デフォルトのタイプの自動化フローです。

順次 DSL の例

以下は、開始条件、条件、アクションで構成されるシーケンシャル フローを使用する、非常に基本的な Automation DSL テンプレートです。

import GoogleHomeSDK
import GoogleHomeTypes

automation (
...
) {
  starter(...)
  condition {...}
  action {...}
}

これは、ノードを追加することで調整できます。

Starter

開始条件ノードは、自動化を有効にする初期条件を定義します。たとえば、状態や値の変更などです。自動化には少なくとも 1 つの開始条件が必要です。そうでない場合、検証に失敗します。自動化に複数の開始条件を追加するには、select ノードを使用する必要があります。

特性属性に基づく開始条件

トレイト属性に基づくスターター ノードを宣言する場合は、以下を指定します。

  • デバイス
  • トレイトが属するデバイスタイプ
  • トレイト
starter(
  thermostat,
  Matter.TemperatureSensorDeviceType.self,
  Matter.TemperatureMeasurementTrait.self
)

デバイスタイプ パラメータは、自動化が対象とするデバイス内のデバイスタイプを指定できるため、必須です。たとえば、デバイスが FanDeviceType と HeatingCoolingUnitDeviceType で構成され、どちらにも OnOffTrait トレイトが含まれている場合があります。デバイスタイプを指定することで、デバイスのどの部分が自動化をトリガーするかが明確になります。

イベントに基づくスターター

イベントに基づく開始ノードを宣言する場合は、以下を指定します。

  • デバイス
  • トレイトが属するデバイスタイプ
  • イベント
starter(
  doorbell,
  Google.GoogleDoorbellDeviceType.self,
  Google.DoorbellPressTrait.DoorbellPressedEvent
)

ストラクチャとイベントに基づく開始条件(パラメータあり)

一部のイベントにはパラメータを指定できるため、これらのパラメータもスターターに含める必要があります。

たとえば、次の開始条件では、TimeTrait の ScheduledEvent を使用して、午前 7 時に自動化を有効にします。

typealias TimeTrait = Google.TimeTrait

let earlyMorning = starter(
  structure,
  TimeTrait.ScheduledEvent.self
) {
  TimeTrait.ScheduledEvent.clockTime(TimeOfDay(hours: 7, minutes: 0))
}

天候に基づく開始条件

Weather トレイトを使用して、現在の気象条件または天気予報をスターターで指定できます。

let weatherState = starter<_>(structure, trait = Weather)

自動化の例ページの雨が降りそうな場合はブラインドを閉じるをご覧ください。

手動開始イベント

手動開始条件は、ユーザーが自動化を手動で実行できるようにする特別なタイプの開始条件です。

手動開始イベントを宣言する場合:

  • トレイトやデバイスタイプは指定しないでください。
  • Automation.execute() を呼び出す UI 要素を指定します。

手動開始条件を別の開始条件とともに select フローに配置すると、手動開始条件が他の開始条件をオーバーライドします。

select {
  manualStarter()
  starter(
    thermostat,
    Matter.TemperatureSensorDeviceType.self,
    Matter.TemperatureMeasurementTrait.self
  )
}

手動開始条件に続く condition ノードは評価され、condition 式によっては自動化の実行がブロックされる可能性があります。

手動の開始条件を条件付きの開始条件から分離する

condition ノードが手動開始条件で有効化された自動化をブロックしないように自動化を構成する方法の 1 つは、別の開始条件を condition とともに別のシーケンシャル フローに配置することです。

import GoogleHomeSDK
import GoogleHomeTypes

automation (
...
) {

  select {
    sequential {
      starter(...)
      condition {...}
    }
    sequential {
      manualStarter()
    }
  }
  action {...}

}

属性の値を参照する

式で属性の値を使用するには、次の構文を使用します。

stateReader の場合:

typealias TimeTrait = Google.TimeTrait

let time = stateReader(structure, TimeTrait.self)
time
let currTime = time.currentTime

starter の場合:

typealias LaundryWasherDeviceType = Matter.LaundryWasherDeviceType
typealias OnOffTrait = Google.OnOffTrait

let starterNode = starter(device1, LaundryWasherDeviceType.self, OnOffTrait.self)
starterNode
condition {
  starterNode.onOff.equals(true)
}

条件ノードと式

条件ノードは、自動化を続行するかどうかを決定する決定ポイントを表します。1 つの自動化に複数の condition ノードを含めることができます。condition ノードの式が false と評価された場合、自動化全体の実行が終了します。

condition ノード内では、式が単一のブール値に評価される限り、さまざまな演算子を使用して複数の条件を組み合わせることができます。結果の値が true の場合、条件が満たされ、自動化は次のノードの実行を続行します。false の場合、自動化はその時点で実行を停止します。

式は Swift の式と同様に形成され、数値、文字、文字列、ブール値などのプリミティブ値と列挙値を含めることができます。サブ式をかっこでグループ化すると、評価の順序を制御できます。

複数の部分式を 1 つの式に結合する condition の例を次に示します。

condition {
  let exp1 = starterNode.lockState.equals(.unlocked)
  let exp2 = stateReaderNode.lockState.equals(true)
  let exp3 = occupancySensingDevice.occupied.notEquals(0)
  (exp1.and(exp2)).or(exp3)
}

スターターを介してアクセスされるトレイトの値を参照できます。

typealias OnOffTrait = Matter.OnOffTrait

let starterNode = starter(device, OnOffTrait.self)
starterNode
condition {
  starterNode.onOff.equals(true)
}
val starterNode = starter<_>(device, OnOff)
condition() { expression = starterNode.onOff equals true }

stateReader

condition ノードでトレイト属性値を参照するもう 1 つの方法は、stateReader ノードを使用することです。

これを行うには、まず stateReader ノードでトレイト属性値をキャプチャします。stateReader は、structure とトレイトを引数として受け取ります。

typealias ActivatedCarbonFilterMonitoringTrait = Matter.ActivatedCarbonFilterMonitoringTrait

let filterMonitoringState = stateReader(structure, ActivatedCarbonFilterMonitoringTrait.self)

次に、condition ノードで stateReader を参照します。

condition {
filterMonitoringState.changeIndication.equals(.warning)
}

比較演算子と論理演算子を使用すると、condition ノードで複数の stateReaders を使用できます。

typealias ArmDisarm = Google.ArmDisarmTrait
typealias DoorLockDevice = Matter.DoorLockDeviceType
typealias DoorLock = Matter.DoorLockTrait

let armState = stateReader(doorLock, DoorLockDevice.self, ArmDisarm )
let doorLockState = stateReader(doorLock, DoorLockDevice.self, DoorLock)
armState
doorLockState
condition {
  let exp1 = armState.armState
  let exp2 = doorLockState.lockState
  exp1.and(exp2)
}

条件の期間

条件のブール式に加えて、自動化を実行するために式が true である必要がある期間を指定できます。たとえば、ライトが 10 分間点灯している場合にのみトリガーされる条件を定義できます。

condition(for: .seconds(600)) {
lightStateReader.onOff.equals(true)
}

期間は 1 ~ 30 分の範囲で指定できます。

アクション ノード

アクション ノードは、自動化の作業が行われる場所です。この例では、アクションは AssistantBroadcastTrait の broadcast() コマンドを呼び出します。

action(speaker, SpeakerDeviceType.self) {
  Google.AssistantBroadcastTrait.broadcast(msg: "Oven Cycle Complete")
}