Android DSL のコンセプト

ここでは、Android の Automation DSL の基本的なコンセプトの概要について説明します。

自動化コンポーネント

自動化は、次の基本コンポーネントで構成されます。通常、次の順序で評価されます。

  1. 開始条件 - トレイトの変更など、自動化を有効にする初期条件を定義します。自動化には開始条件が必要です。
  2. 条件 - 自動化が有効になった後に評価する追加の制約。自動化のアクションを進めるには、Condition の式が true に評価される必要があります。
  3. アクション - すべての条件が満たされたときに実行されるコマンドまたは状態の更新。

たとえば、日の入りから日の出までの間に部屋のテレビの電源がオンになったときに、部屋の照明を暗くする自動化を設定しているとします。この例では、次のようになります。

  1. Starter - テレビの電源がオンになりました。これは、テレビの特性の状態の変化です。
  2. 条件 - テレビが設置されている家の現在の時刻が評価されます。
  3. アクション - テレビと同じ部屋の照明が暗くなります。

部屋のテレビの電源がオンになると自動化が有効になりますが、自動化が実行されるのは「時間が日の入りから日の出までの間」という条件が満たされた場合のみです。

Home API の自動化には、基本構造に加えて、名前説明などのメタデータも含まれています。このメタデータは、デベロッパーやユーザーが自動化を識別するために使用できます。

ノード

Home API では、自動化の論理構造はノードで構成されます。ノードは、エンティティの動作または実行フローを表す抽象的な再利用可能な単位です。各ノードには入力変数と、他のノードで使用される出力変数があります。

表: 自動化ノードのタイプ
ノード ノードタイプ Kotlin の実装 説明
Starter 行動 StarterNodeDsl 特性の状態(任意の属性)が変化したときに自動化を開始します。
StateReader 行動 StateReaderNodeDsl 特性属性を読み取り、条件ノードで使用する値をキャプチャできるようにします。
アクション 行動 ActionNodeDsl トレイト コマンドを呼び出します。
順次 実行フロー SequentialFlow ネストされたアクション ノードを順番に実行します。これがデフォルトの実行動作です。
Parallel 実行フロー ParallelFlow ネストされたアクション ノードを並列で実行します。
条件 実行フロー ConditionNodeDsl 論理式の評価に基づいて実行フローを条件付きで変更します。条件は、開始条件に関連付ける(開始条件固有の条件)ことも、グローバルにする(すべての開始条件に適用する)こともできます。
選択 実行フロー SelectFlow 複数の開始条件で自動化を有効にできます。
Expression Expression 特性の属性の値、定数、リテラル値のいずれかであり、リスト、数値、ブール値、文字列のいずれかに評価される必要があります。

行動ノード

開始条件やアクションなどのノードは、動作ノードです。開始条件は、デバイスの属性の変化に基づいて自動化を有効にします。アクションは、デバイス コマンドを発行するか、属性を更新します。

動作ノードは通常、デバイス特性に関連付けられ、他のノードの入力として使用する特性状態を出力します。

実行フローノード

一部のノードは、実行フロー(順次実行や並列実行など)を表します。これらの各ノードには、自動化を定義する動作ノードが含まれています。

たとえば、順次フローには、順次実行されるノードが含まれる場合があります。通常、これらは開始条件、条件、アクションです。

順次実行フロー
図 1: 順次自動化フロー

並列フローでは、複数のアクション ノードを同時に実行できます(複数の照明を同時に点灯するなど)。並列フローに続くノードは、並列フローのすべてのブランチが完了するまで実行されません。

並列実行フロー
図 2: 並列自動化フロー

もう 1 つの実行フローのタイプは条件フローです。条件フローでは、式の評価に基づいて実行フローを変更できます。

たとえば、夜間かどうかによってアクションを実行する自動化があるとします。条件ノードは時刻を確認し、その評価に基づいて適切な実行パスをたどります。

条件フロー
図 3: 条件フロー

選択フローは、自動化を有効にできるスターターを複数用意する場合に便利です。2 つ以上の開始条件を select フローで囲むと、いずれかの開始条件で自動化を有効にできます。

たとえば、日没時、温度が特定のしきい値を超えた場合、または明るさがしきい値を超えた場合にブラインドを下げる自動化を作成できます。3 つの個別のスターターがこれらの各シナリオを処理し、3 つすべてが select フローにラップされます。

フローを選択
図 4: フローの選択

ネストされたフロー

複雑な自動化では、実行フローノードをネストすることもできます。たとえば、並列フローを実行する順次フローがある場合があります。

ネストされた実行フロー
図 5: ネストされた実行フロー

DSL ノードは、次の表に示す制約に従って、特定のニーズを満たすためにさまざまな方法でネストして組み合わせることができます。[Builder] 列には、Kotlin のタイプセーフ ビルダーのドキュメントへのリンクが記載されています。このドキュメントには、各タイプのノードで使用できる内容が詳しく説明されています。

表: ノードの組み合わせ方
ノード 次のノードタイプとデータが含まれる場合があります 次のいずれかのノードタイプ内にある必要があります
Starter [Sequential] を選択します。
ManualStarter [Sequential] を選択します。
StateReader 式(通常は特性属性値で構成されます) Action、Condition
アクション Command、Entity、Expression Parallel、Select、Sequential
順次 Parallel、Select、Sequential
Parallel アクション 順次
条件 Parallel、Sequential
選択 Condition、Sequential、Starter、ManualStarter 順次実行。フローの最初のノードにする必要があります。

自動化 DSL

Home API では、自動化は Automation DSL(ドメイン固有言語)を使用して定義されます。Automation DSL は、Kotlin タイプセーフ ビルダーを使用して Kotlin DSL(ドメイン固有言語)として実装されており、自動化テンプレートを定義するために特別に設計されています。

自動化がコンパイルされると、Kotlin 型安全ビルダーが Kotlin データクラスを生成し、それがプロトコル バッファ JSON にシリアル化されます。この JSON は、Google の自動化サービスへの呼び出しに使用されます。

Automation DSL は、自動化の構築プロセスを簡素化し、効率化します。Device API で使用されている Matter 標準トレイトと smart home トレイトの同じデータモデルをネイティブに使用します。

Automation DSL は、ユーザーの家にある特定のデバイス インスタンスではなく、抽象的なデバイスタイプで自動化のロジックを定義します。これにより、デベロッパーは、実行時に実際のデバイス インスタンスやその他の重要なパラメータ値を指定するために使用できる入力パラメータを指定できます。

DSL 構文は Kotlin の構文に似ており、同様に型安全ですが、Automation DSL で記述された自動化は、純粋な Kotlin で記述された同じ自動化よりもシンプルで簡潔です。

次の例は、Automation DSL を使用して記述された、デバイスをオンにする自動化の例です。

val automation = automation {
  name = "MyFirstAutomation"
  description = "If light1 is on, turn on light2."
  isActive = true
  sequential {
    val onOffTrait = starter<_>(device1, OnOffLightDevice, OnOff)
    condition() { expression = onOffTrait.onOff equals true }
    action(device2, OnOffLightDevice) { command(OnOff.on()) }
  }
}

この自動化は非常に基本的なものです。device1(ライト)がオンになると(onOff 属性が true に変わると)、on() コマンドを送信して device2 をオンにします。

この自動化では sequential ノードが使用されています。これは、ノードが順番に実行されることを示しています。

sequential ノード内には、starterconditionaction などの動作ノードがあります。starter ノードの出力は、condition ノードで使用する変数に割り当てられます。