Concepts du DSL Android

Voici un aperçu des concepts fondamentaux du DSL d'automatisation sur Android.

Composants d'automatisation

Une automatisation se compose des éléments de base suivants, généralement évalués dans cet ordre :

  1. Déclencheur : définit les conditions initiales qui activent l'automatisation, comme la modification d'une caractéristique. Une automatisation doit avoir un déclencheur.
  2. Condition : toute contrainte supplémentaire à évaluer après l'activation d'une automatisation. L'expression d'une condition doit renvoyer true pour que les actions d'une automatisation puissent se poursuivre.
  3. Action : commandes ou mises à jour d'état effectuées lorsque toutes les conditions sont remplies.

Par exemple, vous avez peut-être une automatisation qui tamise les lumières d'une pièce lorsque le téléviseur de cette pièce est allumé entre le coucher et le lever du soleil. Dans cet exemple :

  1. Déclencheur : le téléviseur a été allumé, ce qui correspond à un changement d'état d'un trait de téléviseur.
  2. Condition : l'heure actuelle de la maison où se trouve le téléviseur est évaluée.
  3. Action : les lumières de la pièce où se trouve le téléviseur sont tamisées.

L'automatisation est activée lorsque le téléviseur de la pièce est allumé, mais elle ne s'exécute que si la condition "l'heure est comprise entre le coucher et le lever du soleil" est remplie.

En plus de la structure de base, les automatisations des API Home contiennent également des métadonnées, telles que name et description, qui peuvent être utilisées pour les identifier pour les développeurs et les utilisateurs.

Nœuds

Dans les API Home, la structure logique d'une automatisation se compose de nœuds. Les nœuds sont des unités abstraites et réutilisables qui représentent des comportements d'entité ou des flux d'exécution. Chaque nœud peut avoir des variables d'entrée, ainsi que des variables de sortie qui peuvent être utilisées par d'autres nœuds.

Tableau : Types de nœuds d'automatisation
Nœud Type de nœud Implémentation en Kotlin Description
Starter Comportement StarterNodeDsl Lance une automatisation lorsque l'état d'un trait (n'importe quel attribut) change.
StateReader Comportement StateReaderNodeDsl Lit un attribut de trait et vous permet de capturer sa valeur pour l'utiliser dans des nœuds de condition.
Action Comportement ActionNodeDsl Appelle une ou plusieurs commandes de trait.
Séquentielle Flux d'exécution SequentialFlow Exécute les nœuds d'action imbriqués en séquence. Il s'agit du comportement d'exécution par défaut.
Parallel Flux d'exécution ParallelFlow Exécute des nœuds d'action imbriqués en parallèle.
Condition Flux d'exécution ConditionNodeDsl Modifiez de manière conditionnelle le flux d'exécution en fonction des évaluations des expressions logiques. Les conditions peuvent être associées à un déclencheur (conditions spécifiques au déclencheur) ou être globales (s'appliquer à tous les déclencheurs).
Sélectionner Flux d'exécution SelectFlow Permet à plusieurs déclencheurs d'activer une automatisation.
IfFlow Flux d'exécution IfFlowDsl Exécute au maximum une action (ou une branche) en fonction de la condition (le cas échéant) qui renvoie la valeur "true" (semblable à une instruction if-then-else).
Expression Valeur Expression Il peut s'agir de la valeur de l'attribut d'un trait, d'une constante ou d'une valeur littérale, et doit correspondre à une liste, un nombre, une valeur booléenne ou une chaîne.

Nœuds comportementaux

Les nœuds tels que les déclencheurs et les actions sont des nœuds comportementaux. Les déclencheurs activent une automatisation en fonction des modifications des attributs de l'appareil. Les actions émettent des commandes d'appareil ou mettent à jour des attributs.

Les nœuds de comportement sont généralement liés aux caractéristiques de l'appareil et à l'état des caractéristiques de sortie, qui sont utilisés comme entrées dans d'autres nœuds.

Nœuds de flux d'exécution

Certains nœuds représentent des flux d'exécution, tels que séquentiels et parallèles. Chacun de ces nœuds contient les nœuds de comportement qui définissent l'automatisation.

Par exemple, un flux séquentiel peut contenir des nœuds qui s'exécutent de manière séquentielle. En général, il s'agit d'un déclencheur, d'une condition et d'une action.

Flux d'exécution séquentiels
Figure 1 : Flux d'automatisation séquentiel

Un flux parallèle peut comporter plusieurs nœuds d'action s'exécutant en même temps, par exemple pour allumer plusieurs lumières simultanément. Les nœuds qui suivent un flux parallèle ne s'exécutent pas tant que toutes les branches du flux parallèle ne sont pas terminées.

Flux d'exécution parallèles
Figure 2 : Flux d'automatisation parallèle

Un autre type de flux d'exécution est un flux de condition, qui peut modifier le flux d'exécution en fonction de l'évaluation d'une expression.

Par exemple, vous avez peut-être une automatisation qui effectue une action en fonction de l'heure de la nuit. Un nœud de condition vérifie l'heure, puis suit le chemin d'exécution approprié en fonction de cette évaluation.

Flux de condition
Figure 3 : Flux de condition

Un flux de sélection est utile lorsque vous souhaitez disposer de plusieurs déclencheurs pour activer votre automatisation. Lorsque vous incluez au moins deux déclencheurs dans un flux select, n'importe lequel d'entre eux peut activer l'automatisation.

Par exemple, vous pouvez créer une automatisation qui baisse les stores au coucher du soleil, si la température dépasse un certain seuil ou si la luminosité dépasse un seuil. Trois déclencheurs distincts gèrent chacun de ces scénarios, et tous les trois sont encapsulés dans un flux select.

Sélectionner un flux
Figure 4 : Sélectionner un flux

Un flux if-then-else (IfFlow) permet d'exécuter des conditions de branchement dans une automatisation. Contrairement à un nœud condition, qui arrête l'ensemble de l'automatisation si la condition est false, un flux if-then-else exécute de manière conditionnelle des actions spécifiques lorsqu'une condition est vraie, et peut se rabattre sur d'autres conditions ou actions de remplacement, ou passer aux nœuds suivants de l'automatisation. Pour en savoir plus, consultez Exécution conditionnelle.

Flux imbriqués

Dans les automatisations complexes, les nœuds de flux d'exécution peuvent également être imbriqués. Par exemple, vous pouvez avoir un flux séquentiel qui exécute un flux parallèle.

Flux d'exécution imbriqués
Figure 5 : Flux d'exécution imbriqués

Les nœuds DSL peuvent être imbriqués et combinés de différentes manières pour répondre à vos besoins spécifiques, en fonction des contraintes décrites dans le tableau suivant. La colonne "Builder" renvoie vers la documentation du compilateur Kotlin avec sûreté de typage, qui détaille ce qui est autorisé pour chaque type de nœud.

Tableau : Comment les nœuds peuvent être combinés
Nœud Peut contenir le type de nœud et les données suivants Doit se trouver dans l'un des types de nœuds suivants
Starter Expression Sélectionner, Séquentiel
ManualStarter Sélectionner, Séquentiel
StateReader Expression (généralement constituée d'une valeur d'attribut de trait) IfFlow, Parallel, Sequential
Action Commande, entité, expression IfFlow, Parallel, Select, Sequential
Séquentielle IfFlow, Parallel, Select, Sequential
Parallel Action IfFlow, Sequential
Condition Expression IfFlow, Parallel, Sequential
Sélectionner Condition, Sequential, Starter, ManualStarter Séquentiel, et doit être le premier nœud du flux
IfFlow Action, Condition, Delay, IfFlow, Parallel, Sequential, StateReader, Suppression Séquentielle

DSL d'automatisation

Dans les API Home, les automatisations sont définies à l'aide du DSL (Domain-Specific Language) d'automatisation. Le DSL d'automatisation est implémenté en tant que DSL Kotlin (langage spécifique au domaine), à l'aide de compilateurs Kotlin avec sûreté de typage. Il est spécialement conçu pour définir des modèles d'automatisation.

Lorsqu'une automatisation est compilée, les compilateurs Kotlin de sûreté du typage génèrent des classes de données Kotlin qui sont ensuite sérialisées au format JSON de tampon de protocole, qui est utilisé pour appeler les services d'automatisation de Google.

Le DSL d'automatisation simplifie et rationalise le processus de création d'automatisations. Il utilise de manière native le même modèle de données des caractéristiques standards Matter et des caractéristiques smart home de l'API Device.

Le DSL d'automatisation définit également la logique d'une automatisation en termes de types d'appareils abstraits, par opposition aux instances d'appareils spécifiques situées dans la maison d'un utilisateur. Il permet au développeur de fournir des paramètres d'entrée qui peuvent être utilisés au moment de l'exécution pour spécifier des instances d'appareil réelles, ainsi que d'autres valeurs de paramètres importantes.

La syntaxe du DSL est semblable à celle de Kotlin et offre la même sûreté du typage. Toutefois, une automatisation écrite dans le DSL d'automatisation est plus simple et plus concise que la même automatisation écrite en Kotlin pur.

Exemple

Voici un exemple d'automatisation qui allume un appareil, écrit à l'aide du DSL d'automatisation :

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()) }
  }
}

Cette automatisation est très simple : lorsque device1, une lumière, s'allume (l'attribut onOff passe à true), elle envoie la commande on() pour activer device2.

L'automatisation utilise un nœud sequential, ce qui indique que ses nœuds s'exécuteront de manière séquentielle.

Le nœud sequential contient des nœuds de comportement tels que starter, condition et action. La sortie du nœud starter est attribuée à une variable à utiliser dans le nœud condition.