Android の Automation API の概要

自動化は、家の中のタスクとデバイスの設定を自動化する方法です。 自動化は、Google Home エコシステムで、 Google Home app (GHA)のルーティンとして、またautomation script editorGoogle Home for webを通じて利用できるようになりました。

Google Home エコシステムの自動化は、Android 用 Home API を通じて利用できるようになりました。GHA GHAルーティンとscript editorスクリプト エディタで使用されている基本的なコンセプトは同じですが、 Home API を通じてのみ可能な次のような機能が強化されています。

  • Home API に示されているように、デバイスのすべての Matter 標準トレイトと smart home トレイトにアクセスできます。
  • 順次実行、並列実行、選択実行フローをサポートしています。

自動化は、Kotlin で自動化を構築するために設計されたドメイン固有言語である Automation DSL を使用して記述されます。

デバイスと構造 API または Automation API を使用してアプリで使用するトレイトと型は、初期化時に登録する必要があります。Android でホームを初期化するをご覧ください。

ユーザーが完全な権限を取り消した場合のガイダンス

ユーザーが完全な権限を取り消すと、既存の自動化はすべて停止します。また、ユーザーが特定のデバイスへのアクセスを取り消すと、それらのデバイスに関連付けられたスターター、条件、アクションは停止します。

アプリが起動するたびに、権限が有効な状態であることを確認してください。権限が取り消された場合は、アプリケーションにキャッシュされているデータを含め、以前のデータがすべて削除されていることを確認してください。

構造へのアクセスが取り消されると、 StructureAccessRevokedEvent がクラウド バックエンドに配信されます。エンドツーエンドのパートナー クラウドとモバイルアプリの取り消しワークフローについては、 構造の付与をご覧ください。

デベロッパーが実施する手順

Automation API は、大規模な開発プロセスの 1 つの要素です。ユーザーが自動化を使用できるように、構造 API とデバイス API を統合した後に使用します。

  1. デベロッパーは自動化を計画し、Automation DSL を使用して定義します。
  2. デベロッパーは、自動化の定義を Kotlin Android アプリに埋め込みます。
  3. アプリは、Discovery API またはデバイス API を使用して収集したデバイスに関する情報(トレイト、属性、コマンド、イベントなど)に基づいて、自動化をユーザーに提示します。
    1. Discovery API を使用すると、アプリは、ユーザーの入力の有無にかかわらず、ユーザーの構造に存在するデバイスタイプとトレイトに合わせてカスタマイズされた自動化のドラフトを生成できます。
    2. デバイス API は Discovery API とほぼ同じ情報を提供できますが、自動化のユースケースには最適化されていません。詳しくは、 デバイス API と Discovery API の比較 をご覧ください。
  4. アプリは、選択した構造にキー設定された実際の自動化を作成します。
  5. 自動化はユーザーの構造で使用できるようになり、構造 API メソッドを使用して実行または削除できます。

ユーザーは、いつでも自動化の新しいインスタンスを作成し、別の構造を選択したり、アプリのロジックに応じて別のデバイスセットを選択したりできます。そのたびに、アプリは自動化の新しいインスタンスを生成します。

最も基本的なシナリオでは、比較的基本的なタスクを実行する事前定義された自動化をユーザーに提案できます。または、ユーザーがニーズに合わせてカスタマイズできる自動化のスケルトンを提示することもできます。また、ユーザーが Automation API で利用可能なすべてのビルディング ブロックを使用して複雑な自動化を構築できる、オープンエンドの自動化エディタを作成することもできます。

自動化の提案

Home API は、 Structureなどの要素 に基づいて、スペースに存在するデバイスタイプなどの自動化を提案できます。

自動化の候補は AutomationSuggestion クラスで表されます。

Structure インターフェースには、HasSuggestions インターフェースが含まれています。このインターフェースは、自動化の候補のコレクションを返す suggestions() 関数を提供します。

likeSuggestion()dislikeSuggestion() メソッドは、ユーザーがタップしてフィードバックを提供できる の UI コントロールに接続することを目的としています。

3 つ目のメソッド clearSuggestionFeedback(), を使用すると、ユーザーは提案された自動化に対するフィードバックを削除できます。

ユーザーのフィードバックは、今後の候補に影響します。

この例では、Structure で利用可能な自動化の候補 を取得し、候補 ID を抽出し、likeSuggestion()clearSuggestionFeedback()、 および dislikeSuggestion() を使用してユーザーのフィードバックを記録する方法を示します。

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.home.Structure
import kotlinx.coroutines.launch

class AutomationSuggestionsViewModel(private val structure: Structure) : ViewModel() {

  fun loadAndGiveFeedback() {
    viewModelScope.launch {
      // 1. Fetch suggestions from structure
      val suggestions = structure.suggestions()
      val firstSuggestion = suggestions.firstOrNull() ?: return@launch

      // Extract string suggestion ID
      val suggestionId: String = firstSuggestion.id.id

      // 2. Like the suggestion (thumbs up)
      val liked = structure.likeSuggestion(suggestionId)

      // 3. Clear previous feedback if the user toggled it off
      if (liked) {
        structure.clearSuggestionFeedback(suggestionId)
      }

      // 4. Dislike the suggestion (thumbs down)
      structure.dislikeSuggestion(suggestionId)
    }
  }
}

動的コマンド パラメータ

動的コマンド パラメータを使用すると、デベロッパーは、静的な定数値に厳密に依存するのではなく、実行時に動的に解決されるアクション パラメータを構築できます。これにより、次の 2 つの主要な機能が実現します。

  • スターター(イベント ペイロードなど)または状態リーダーノードから、あるいは自動化フロー内で宣言されたローカル変数から、プロパティの値を渡す参照。
  • 実行時の動的な値(イベント プロパティや状態値など)を取得し、動的な値をコマンド パラメータに直接渡す式。

ユースケース

マルチタップ イベントを送信する物理ロータリー スイッチを調光可能なライトにバインドします。クリック数は、実行時に LevelControl ステップ コマンドに渡される動的な値です。

動的パラメータの仕組み

Android の Automation DSL では、コマンド パラメータは Expressionまたは Referenceインスタンスを 静的な定数値の代わりに直接受け取ります。DSL は、自動化の構築時にこれらを Parameter 定義にカプセル化します。

検証規則

動的コマンド パラメータには、次の検証制約が適用されます。

  • Discovery API は静的引数の具体的な値の制約のみを評価するため、検出中に動的パラメータは構造的に有効であると見なされます。
  • 参照ノードまたは式ノードは、ダウンストリームのコマンド アクションで参照される前に、自動化グラフの上流に表示される必要があります。

Android で動的コマンド パラメータを使用する

動的式をコマンド パラメータに直接渡します。

import com.google.home.automation.action
import com.google.home.automation.automation
import com.google.home.automation.fieldSelect
import com.google.home.automation.sequential
import com.google.home.automation.starter
import com.google.home.matter.standard.DimmableLightDevice
import com.google.home.matter.standard.DimmerSwitchDevice
import com.google.home.matter.standard.LevelControl
import com.google.home.matter.standard.LevelControlTrait.StepModeEnum
import com.google.home.matter.standard.Switch

val keypressAutomation = automation {
  name = "Dynamic command parameters example"
  description = "Pass starter event field directly to command"
  sequential {
    val dimmerStarter = starter(
      dimmerSwitch,
      DimmerSwitchDevice,
      Switch.MultiPressOngoingEvent,
    )

    val clickCountExpr = fieldSelect<Switch.MultiPressOngoingEvent, UInt>(
      dimmerStarter,
      Switch.MultiPressOngoingEvent.EventFields.currentNumberOfPressesCounted,
    )

    action(dimmableLight, DimmableLightDevice) {
      command(
        LevelControl.step(
          stepMode = StepModeEnum.Up,
          stepSize = clickCountExpr,
        )
      )
    }
  }
}

または、式をローカル変数宣言に割り当てて、フロー内で後で変数を参照します。

import com.google.home.automation.action
import com.google.home.automation.automation
import com.google.home.automation.fieldSelect
import com.google.home.automation.sequential
import com.google.home.automation.starter
import com.google.home.automation.variable
import com.google.home.matter.standard.DimmableLightDevice
import com.google.home.matter.standard.DimmerSwitchDevice
import com.google.home.matter.standard.LevelControl
import com.google.home.matter.standard.LevelControlTrait.StepModeEnum
import com.google.home.matter.standard.Switch

val myAutomationWithVariable = automation {
  name = "Dynamic command parameters with variables"
  description = "Declare a variable, assign value, and pass reference"
  sequential {
    val dimmerStarter = starter(
      dimmerSwitch,
      DimmerSwitchDevice,
      Switch.MultiPressOngoingEvent,
    )

    val clickCountExpr = fieldSelect<Switch.MultiPressOngoingEvent, UInt>(
      dimmerStarter,
      Switch.MultiPressOngoingEvent.EventFields.currentNumberOfPressesCounted,
    )

    val clickCountVar = variable<UInt>()
    clickCountVar.assign(clickCountExpr)

    action(dimmableLight, DimmableLightDevice) {
      command(
        LevelControl.step(
          stepMode = StepModeEnum.Up,
          stepSize = clickCountVar,
        )
      )
    }
  }
}

型の制約

変数と式の型が、受信 コマンド パラメータに必要な Matter スキーマ型 定義(UShortUByteUInt8 など)と一致していることを確認します。

リソースの上限

Home API の自動化には次の制限が適用されます。

表: Automation API のリソースの上限
指標 上限
構造あたりの自動化の最大数 64
自動化あたりのノードの最大数 128
自動化あたりの式ノードの最大数 64
構造あたりの自動化インスタンスの最大数 1024
構造あたりのデベロッパーあたりの 構造あたりの自動化インスタンスの最大数 64
構造あたりの 1 日あたりの実行回数の最大数 1024
構造あたりのデベロッパーあたりの 1 日あたりの実行回数の最大数 128