本文概略介紹 Android 自動化 DSL 的基本概念。
自動化元件
自動化動作包含下列基本元件,通常會依下列順序評估:
- 啟動條件:定義啟用自動化動作的初始條件,例如特徵變更。自動化動作必須有啟動條件。
- 條件:自動化動作啟用後,要評估的任何其他限制。條件中的運算式必須評估為
true,自動化動作才能繼續執行。 - 動作:符合所有條件時執行的指令或狀態更新。
舉例來說,假設你設定了自動化動作,在日落到日出之間,只要房間的電視開啟,就會調暗房間的燈光。在這個例子中:
- 啟動條件:電視已開啟,這是電視特性的狀態變更。
- 條件:系統會評估電視所在住家的目前時間。
- 動作:電視所在房間的燈光會調暗。
當房間內的電視開啟時,自動化動作就會啟動,但只有在符合「時間介於日落和日出之間」的條件時,自動化動作才會執行。
除了基本結構外,Home API 中的自動化動作也包含中繼資料,例如 name 和 description,可用於向開發人員和使用者識別這些動作。
節點
在 Home API 中,自動化動作的邏輯結構是由節點組成。節點是抽象的可重複使用單位,代表實體行為或執行流程。每個節點都可以有輸入變數,以及可能由其他節點使用的輸出變數。
| 節點 | 節點類型 | Kotlin 實作 | 說明 |
|---|---|---|---|
| Starter | 行為 |
StarterNodeDsl
|
在特性的狀態 (任何屬性) 變更時啟動自動化動作。 |
| StateReader | 行為 |
StateReaderNodeDsl
|
讀取特徵屬性,並擷取其值,以便在條件節點中使用。 |
| 動作 | 行為 |
ActionNodeDsl
|
叫用特徵指令。 |
| 依序 | 執行流程 |
SequentialFlow
|
依序執行巢狀動作節點。這是預設的執行行為。 |
| 平行 | 執行流程 |
ParallelFlow
|
同時執行巢狀動作節點。 |
| 狀況 | 執行流程 |
ConditionNodeDsl
|
根據邏輯運算式的評估結果,有條件地變更執行流程。條件可以與啟動條件建立關聯 (啟動條件專屬條件),也可以是全域條件 (適用於所有啟動條件)。 |
| 選取 | 執行流程 |
SelectFlow
|
允許使用多個啟動條件來啟動自動化動作。 |
| IfFlow | 執行流程 |
IfFlowDsl
|
根據評估為 true 的條件 (如有),執行最多一個動作 (或分支) (類似於 if-then-else 陳述式)。 |
| 運算式 | 值 |
Expression
|
可以是特徵屬性的值、常數或常值,且必須評估為清單、數字、布林值或字串。 |
行為節點
啟動條件和動作等節點屬於行為節點。啟動條件會根據裝置屬性變更啟動自動化動作。動作會發出裝置指令或更新屬性。
行為節點通常與裝置特性和輸出特性狀態相關聯,可做為其他節點的輸入內容。
執行流程節點
部分節點代表執行流程,例如依序和並行。每個節點都包含定義自動化動作的行為節點。
例如,「依序」流程可能包含依序執行的節點。通常是啟動條件、限制條件和動作。
平行流程可能有多個動作節點同時執行,例如同時開啟多盞燈。平行流程後方的節點,會等到平行流程的所有分支都完成後才執行。
另一種執行流程是「條件流程」,可根據運算式的評估結果變更執行流程。
舉例來說,您可能有一個自動化動作,會根據是否為夜間執行動作。條件節點會檢查時間,然後根據評估結果,遵循適當的執行路徑。
如果想讓多個啟動條件都能觸發自動化動作,可以使用選取流程。在 select 流程中加入兩個以上的啟動條件時,只要符合其中一個條件,就會啟動自動化動作。
舉例來說,你可以編寫自動化動作,在日落時、溫度高於特定門檻,或亮度超過門檻時,降低百葉窗。這三種情況分別由三個獨立的啟動器處理,且這三個啟動器都會包裝在 select 流程中。
if-then-else 流程 (IfFlow) 可在自動化動作中執行分支條件式。如果條件為 false,condition 節點會停止整個自動化動作,但 if-then-else 流程則不同,會在條件為 true 時,有條件地執行特定動作,並可改用替代條件或備用動作,或繼續執行自動化動作中的後續節點。詳情請參閱「條件式執行」。
巢狀流程
在複雜的自動化動作中,執行流程節點也可以巢狀。例如,您可能會有執行平行流程的依序流程。
您可以根據下表所述的限制,以各種方式巢狀和組合 DSL 節點,以符合特定需求。「Builder」欄會連結至 Kotlin 類型安全建構工具說明文件,詳細說明每種節點允許使用的內容。
| 節點 | 可能包含下列節點類型和資料 | 必須屬於下列其中一種節點類型 |
|---|---|---|
| Starter | 運算式 | 選取「依序」 |
| ManualStarter | 選取「依序」 | |
| StateReader | 運算式 (通常由特徵屬性值組成) | IfFlow、Parallel、Sequential |
| 動作 | 指令、實體、運算式 | IfFlow、Parallel、Select、Sequential |
| 依序 | IfFlow、Parallel、Select、Sequential | |
| 平行 | 動作 | IfFlow、Sequential |
| 狀況 | 運算式 | IfFlow、Parallel、Sequential |
| 選取 | Condition、Sequential、Starter、ManualStarter | 依序,且必須是流程中的第一個節點 |
| IfFlow | Action、Condition、Delay、IfFlow、Parallel、Sequential、StateReader、Suppression | 循序 |
自動化動作 DSL
在 Home API 中,自動化動作是使用自動化動作 DSL (特定領域語言) 定義。自動化動作 DSL 是以 Kotlin DSL (網域特定語言) 的形式實作,使用 Kotlin 類型安全建構工具,專門用於定義自動化動作範本。
編譯自動化動作時,Kotlin 類型安全建構工具會產生 Kotlin 資料類別,然後序列化為通訊協定緩衝區 JSON,用於呼叫 Google 的自動化服務。
自動化 DSL 可簡化建構自動化動作的程序。它原生使用與 Device API 中 Matter 標準特徵和 smart home 特徵相同的資料模型。
自動化動作 DSL 也會根據抽象裝置類型定義自動化動作的邏輯,而非使用者住家中的特定裝置執行個體。開發人員可以提供輸入參數,在執行階段指定實際裝置執行個體,以及其他重要參數值。
DSL 語法與 Kotlin 類似,且同樣具有類型安全,但以 Automation DSL 編寫的自動化動作,比以純 Kotlin 編寫的相同自動化動作更簡單、更精簡。
範例
以下是使用自動化動作 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 節點內有行為節點,例如 starter、condition 和 action。starter 節點的輸出內容會指派給變數,以便在 condition 節點中使用。