DSL ガイド - 基本的な自動化

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

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

順次フロー

順序型フローは、自動化フローのデフォルト タイプです。

シーケンシャル DSL の例

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


import com.google.home.automation.action
import com.google.home.automation.automation
import com.google.home.automation.condition
import com.google.home.automation.sequential
import com.google.home.automation.starter

...

automation {
  sequential {
    starter<_>(...)
    condition {...}
    action {...}
  }
}

ノードを追加することで、このモデルを絞り込むことができます。

Starter

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

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

トレイト属性に基づく開始ノードを宣言する場合は、次のように指定します。

  • デバイス
  • トレイトが属するデバイスタイプ
  • 特性
starter<_>(thermostat, TemperatureSensorDevice, TemperatureMeasurement)

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

イベントベースの開始条件

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

  • デバイス
  • トレイトが属するデバイスタイプ
  • イベント
starter<_>(doorBell, GoogleDoorbellDevice, DoorbellPressed)

構造とイベントに基づく開始条件(パラメータあり)

イベントによってはパラメータが設定されるため、これらのパラメータも開始条件に含める必要があります。

たとえば、この開始条件では、Time トレイトの ScheduledTimeEvent を使用して、午前 7 時に自動化を有効にします。

val earlyMorning = starter<_>(structure, Time.ScheduledTimeEvent) {
  parameter(Time.ScheduledTimeEvent.clockTime(
    LocalTime.of(7, 0, 0, 0)))
}

手動スターター

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

手動開始条件を宣言する場合:

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

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

select {
  manualStarter()
  starter<_>(thermostat, TemperatureSensorDevice, TemperatureMeasurement)
}

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

手動開始条件と条件を分離する

condition ノードが手動開始条件で有効になった自動化をブロックしないように自動化を構成する方法の一つは、他の開始条件をその condition とともに別の順序フローに入れる方法です。

automation_graph {
  sequential {
    select {
      sequential {
        starter<_>(...)
        condition {...}
      }
      sequential {
        manualStarter()
      }
    }
    action {...}
  }
}

属性の値を参照する

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

stateReader の場合:

val time = stateReader<_>(structure, Structure, Time)
val currTime = time.currentTime

starter の場合:

val starterNode = starter<_>(device1, LaundryWasherDevice, OnOff)
condition() {
  expression = starterNode.onOff equals true
}

条件ノードと式

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

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

式は Kotlin の式と同様の方法で作成され、数値、文字、文字列、ブール値などのプリミティブ値や、列挙型の値を含めることができます。サブ式を括弧でグループ化すると、評価順序を制御できます。

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

condition() {
  val expr1 = starterNode.lockState equals DlLockState.Unlocked
  val expr2 = stateReaderNode.lockState equals true

  val expr3 = occupancySensingDevice.occupied notEquals 0
  val expr4 = timeStateReaderNode
    .currentTime
    .between(
      timeStateReaderNode.sunsetTime,
      timeStateReaderNode.sunriseTime)
  expression = (expr1 and expr2) or (expr3 and expr4)
}

開始条件でアクセスしたトレイトの値を参照できます。

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

stateReader

condition ノードで特徴属性の値を参照するもう 1 つの方法は、stateReader ノードを使用する方法です。

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

import com.google.home.automation.stateReader
...
val filterMonitoringState = stateReader<_>(structure, ActivatedCarbonFilterMonitoring)

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

condition() {
  expression =
    filterMonitoringState.changeIndication
      .equals(ChangeIndicationEnum.Warning)
}

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

val armState = stateReader<_>(doorLock, DoorLockDevice, ArmDisarm )
val doorLockState = stateReader<_>(doorLock, DoorLockDevice, DoorLock)
condition() {
  expression =
    (armState.armState equals true)
    and
    (doorLockState.lockState equals true)
}

条件の継続時間

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

  condition {
    expression(lightStateReader.onOff == true)
    forDuration(Duration.ofMinutes(10))
  }

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

アクションノード

アクションノードでは、自動化の処理が行われます。この例では、アクションが AssistantBroadcast トレイトの broadcast() コマンドを呼び出します。

action(device, SpeakerDevice) {
  command(AssistantBroadcast.broadcast("Intruder detected!"))
}

インポート ステートメント

自動化を開発する際に、Home API のさまざまな要素をコードにインポートする方法が明確でない場合があります。

特徴属性は、特徴の Companion オブジェクトからインポートされます。

import com.google.home.matter.standard.OnOff.Companion.onOff

トレイトによって定義されたデータ構造は、名前が「-Trait」で終わるトレイトクラスからインポートされます。

import com.google.home.matter.standard.MediaPlaybackTrait.PlaybackStateEnum

トレイト コマンドは、トレイトの Companion オブジェクトからインポートされます。

import com.google.home.matter.standard.Thermostat.Companion.setTemperatureSetpointHold