Questa è una panoramica dei concetti fondamentali della DSL di automazione su Android.
Componenti di automazione
Un'automazione è costituita dai seguenti componenti di base, in genere valutati in questo ordine:
- Comando iniziale : definisce le condizioni iniziali che attivano l'automazione, ad esempio una modifica a un tratto. Un'automazione deve avere un comando iniziale.
- Condizione : eventuali vincoli aggiuntivi da valutare dopo l'attivazione di un'automazione. L'espressione in una condizione deve essere valutata come
trueaffinché le azioni di un'automazione possano procedere. - Azione : comandi o aggiornamenti di stato eseguiti quando tutte le condizioni sono state soddisfatte.
Ad esempio, potresti avere un'automazione che attenua le luci in una stanza quando la TV nella stanza viene accesa tra il tramonto e l'alba. In questo esempio:
- Comando iniziale : la TV è stata accesa, il che rappresenta una modifica dello stato di un tratto della TV.
- Condizione : viene valutata l'ora corrente della casa in cui si trova la TV.
- Azione : le luci nella stessa stanza della TV vengono attenuate.
L'automazione viene attivata quando la TV nella stanza viene accesa, ma viene eseguita solo se la condizione "l'ora è compresa tra il tramonto e l'alba" è soddisfatta.
Oltre alla struttura di base, le automazioni nelle API Home contengono anche metadati, come nome e descrizione, che possono essere utilizzati per identificarli per sviluppatori e utenti.
Nodi
Nelle API Home, la struttura logica di un'automazione è costituita da nodi. I nodi sono unità astratte e riutilizzabili che rappresentano i comportamenti delle entità o i flussi di esecuzione. Ogni nodo può avere variabili di input, nonché variabili di output che possono essere utilizzate da altri nodi.
| Nodo | Tipo di nodo | Implementazione Kotlin | Descrizione |
|---|---|---|---|
| Comando iniziale | Comportamentale |
StarterNodeDsl
|
Avvia un'automazione quando lo stato di un tratto (qualsiasi attributo) cambia. |
| StateReader | Comportamentale |
StateReaderNodeDsl
|
Legge un attributo del tratto e ti consente di acquisirne il valore per utilizzarlo nei nodi delle condizioni. |
| Azione | Comportamentale |
ActionNodeDsl
|
Richiama i comandi del tratto. |
| Sequenziale | Flusso di esecuzione |
SequentialFlow
|
Esegue i nodi delle azioni nidificate in sequenza. Questo è il comportamento di esecuzione comportamento. |
| Parallelo | Flusso di esecuzione |
ParallelFlow
|
Esegue i nodi delle azioni nidificate in parallelo. |
| Condizione | Flusso di esecuzione |
ConditionNodeDsl
|
Modifica in modo condizionale il flusso di esecuzione in base alle valutazioni delle espressioni logiche. Le condizioni possono essere associate a un comando iniziale (condizioni specifiche del comando iniziale) o essere globali (si applicano a tutti i comandi iniziali). |
| Seleziona | Flusso di esecuzione |
SelectFlow
|
Consente a più di un comando iniziale di attivare un'automazione. |
| Espressione | Valore |
Expression
|
Può essere il valore di un attributo del tratto, una costante o un valore letterale, e deve essere valutato come un elenco, un numero, un valore booleano o una stringa. |
Nodi comportamentali
I nodi come i comandi iniziali e le azioni sono nodi comportamentali. I comandi iniziali attivano un'automazione in base alle modifiche degli attributi del dispositivo. Le azioni emettono comandi del dispositivo o aggiornano gli attributi.
I nodi comportamentali sono in genere associati ai tratti del dispositivo e allo stato del tratto di output da utilizzare come input in altri nodi.
Nodi del flusso di esecuzione
Alcuni nodi rappresentano i flussi di esecuzione, come quelli sequenziali e paralleli. Ciascuno di questi nodi contiene i nodi comportamentali che definiscono l'automazione.
Ad esempio, un flusso sequenziale può contenere nodi che vengono eseguiti in ordine sequenziale. In genere, si tratta di comandi iniziali, condizioni e azioni.
Un flusso parallelo può avere più nodi di azioni in esecuzione contemporaneamente, ad esempio l'accensione di più luci contemporaneamente. I nodi che seguono un flusso parallelo non vengono eseguiti finché non vengono completati tutti i rami del flusso parallelo.
Un altro tipo di flusso di esecuzione è un flusso di condizioni, che può modificare il flusso di esecuzione in base alla valutazione di un'espressione.
Ad esempio, potresti avere un'automazione che esegue un'azione in base al fatto che sia notte o meno. Un nodo di condizione controlla l'ora del giorno, quindi segue il percorso di esecuzione appropriato in base a questa valutazione.
Un flusso di selezione è utile quando vuoi avere più di un comando iniziale che può attivare l'automazione. Quando racchiudi due o più comandi iniziali in un flusso select, uno qualsiasi dei comandi iniziali può attivare l'automazione.
Ad esempio, puoi scrivere un'automazione che abbassa le tapparelle al tramonto, se la temperatura supera una determinata soglia o se la luminosità supera una soglia. Tre comandi iniziali separati gestiscono ciascuno di questi scenari e tutti e tre sarebbero racchiusi in un flusso select.
Flussi nidificati
Nelle automazioni complesse, i nodi del flusso di esecuzione possono anche essere nidificati. Ad esempio, potresti avere un flusso sequenziale che esegue un flusso parallelo.
I nodi DSL possono essere nidificati e combinati in vari modi per soddisfare le tue esigenze specifiche, in base ai vincoli indicati nella tabella seguente. La colonna Builder rimanda alla documentazione del builder Kotlin typesafe, che descrive in dettaglio cosa è consentito utilizzare in ogni tipo di nodo.
| Nodo | Può contenere il seguente tipo di nodo e dati | Deve essere all'interno di uno dei seguenti tipi di nodi |
|---|---|---|
| Comando iniziale | Espressione | Seleziona, Sequenziale |
| ManualStarter | Seleziona, Sequenziale | |
| StateReader | Espressione (in genere costituita da un valore dell'attributo del tratto) | Azione, Condizione |
| Azione | Comando, Entità, Espressione | Parallelo, Seleziona, Sequenziale |
| Sequenziale | Parallelo, Seleziona, Sequenziale | |
| Parallelo | Azione | Sequenziale |
| Condizione | Espressione | Parallelo, Sequenziale |
| Seleziona | Condizione, Sequenziale, Comando iniziale, ManualStarter | Sequenziale e deve essere il primo nodo del flusso |
DSL di automazione
Nelle API Home, le automazioni vengono definite utilizzando la DSL di automazione (Domain-Specific Language). La DSL di automazione viene implementata come DSL Kotlin (Domain-Specific Language), utilizzando i builder Kotlin typesafe ed è progettata specificamente per la definizione dei modelli di automazione.
Quando un'automazione viene compilata, i builder Kotlin typesafe generano classi di dati Kotlin che vengono poi serializzate in JSON del buffer di protocollo, utilizzato per effettuare chiamate ai servizi di automazione di Google.
La DSL di automazione semplifica e ottimizza il processo di creazione delle automazioni. Utilizza in modo nativo lo stesso modello di dati dei Matter tratti standard e dei smart home tratti presenti nell'API Device.
La DSL di automazione definisce anche la logica di un'automazione in termini di tipi di dispositivi astratti, anziché di istanze di dispositivi specifici che si trovano nella casa di un utente. Consente allo sviluppatore di fornire parametri di input che possono essere utilizzati in fase di runtime per specificare le istanze di dispositivi effettivi, nonché altri valori di parametri importanti.
La sintassi DSL è simile a quella di Kotlin ed è altrettanto typesafe, ma un'automazione scritta nella DSL di automazione è più semplice e concisa rispetto alla stessa automazione scritta in Kotlin puro.
Esempio
Di seguito è riportato un esempio di automazione che accende un dispositivo, scritto utilizzando la DSL di automazione:
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()) }
}
}
Questa automazione è molto semplice: quando device1, una luce, si accende (l'attributo onOff diventa true), invia il comando on() per accendere device2.
L'automazione utilizza un nodo sequential, che indica che i nodi verranno eseguiti in ordine sequenziale.
All'interno del nodo sequential sono presenti nodi comportamentali come starter, condition e action. L'output del nodo starter viene assegnato a una variabile da utilizzare nel nodo condition.