Esta es una descripción general de los conceptos fundamentales del DSL de Automation en Android.
Componentes de automatización
Una automatización consta de los siguientes componentes básicos, que suelen evaluarse en este orden:
- Activador: Define las condiciones iniciales que activan la automatización, como un cambio en un rasgo. Una automatización debe tener un activador.
- Condición: Son las restricciones adicionales que se deben evaluar después de que se activa una automatización. La expresión de una condición debe evaluarse como
true
para que se ejecuten las acciones de una automatización. - Acción: Son los comandos o las actualizaciones de estado que se realizan cuando se cumplen todas las condiciones.
Por ejemplo, tal vez tengas una automatización que atenúa las luces de una habitación cuando se enciende la TV en esa habitación entre el atardecer y el amanecer. En este ejemplo:
- Starter: Se encendió la TV, lo que representa un cambio de estado en un rasgo de la TV.
- Condición: Se evalúa la hora actual de la casa en la que se encuentra la TV.
- Acción: Las luces de la misma habitación que la TV se atenúan.
La automatización se activaría cuando se encienda la TV de la habitación, pero solo se ejecutará si se cumple la condición de "la hora está entre el atardecer y el amanecer".
Además de la estructura básica, las automatizaciones en las APIs de Home también contienen metadatos, como name y description, que se pueden usar para identificarlas para desarrolladores y usuarios.
Nodos
En las APIs de Home, la estructura lógica de una automatización consta de nodos. Los nodos son unidades abstractas y reutilizables que representan comportamientos de entidades o flujos de ejecución. Cada nodo puede tener variables de entrada y variables de salida que otros nodos pueden consumir.
Nodo | Tipo de nodo | Implementación de Kotlin | Descripción |
---|---|---|---|
Starter | Comportamiento |
StarterNodeDsl
|
Inicia una automatización cuando cambia el estado de un rasgo (cualquier atributo). |
StateReader | Comportamiento |
StateReaderNodeDsl
|
Lee un atributo de rasgo y te permite capturar su valor para usarlo en nodos de condición. |
Acción | Comportamiento |
ActionNodeDsl
|
Invoca comandos de rasgos. |
Secuencial | Flujo de ejecución |
SequentialFlow
|
Ejecuta nodos de acción anidados en secuencia. Este es el comportamiento de ejecución predeterminado. |
Paralelo | Flujo de ejecución |
ParallelFlow
|
Ejecuta nodos de acción anidados en paralelo. |
Afección | Flujo de ejecución |
ConditionNodeDsl
|
Cambiar de forma condicional el flujo de ejecución en función de las evaluaciones de expresiones lógicas Las condiciones pueden estar asociadas con un activador (condiciones específicas del activador) o ser globales (se aplican a todos los activadores). |
Seleccionar | Flujo de ejecución |
SelectFlow
|
Permite que más de un activador inicie una automatización. |
Expresión | Valor |
Expression
|
Puede ser el valor de un atributo del rasgo, una constante o un valor literal, y debe evaluarse como una lista, un número, un valor booleano o una cadena. |
Nodos de comportamiento
Los nodos, como los activadores y las acciones, son nodos de comportamiento. Los activadores activan una automatización según los cambios en los atributos del dispositivo. Las acciones envían comandos a los dispositivos o actualizan atributos.
Por lo general, los nodos de comportamiento se vinculan a rasgos del dispositivo y generan el estado del rasgo para usarlo como entrada en otros nodos.
Nodos de flujo de ejecución
Algunos nodos representan flujos de ejecución, como los secuenciales y los paralelos. Cada uno de estos nodos contiene los nodos de comportamiento que definen la automatización.
Por ejemplo, un flujo secuencial puede contener nodos que se ejecutan en orden secuencial. Por lo general, estos serían el activador, la condición y la acción.
Un flujo paralelo puede tener varios nodos de acción que se ejecutan al mismo tiempo, como encender varias luces simultáneamente. Los nodos que siguen un flujo paralelo no se ejecutarán hasta que finalicen todas las ramas del flujo paralelo.
Otro tipo de flujo de ejecución es un flujo de condición, que puede cambiar el flujo de ejecución según la evaluación de una expresión.
Por ejemplo, tal vez tengas una automatización que realice una acción según si es de noche. Un nodo de condición verifica la hora del día y, luego, sigue la ruta de ejecución adecuada según esa evaluación.
Un flujo de selección es útil cuando deseas tener más de un activador que pueda iniciar tu automatización. Cuando encierras dos o más activadores en un flujo de select
, cualquiera de ellos puede activar la automatización.
Por ejemplo, podrías escribir una automatización que baje las persianas al atardecer, si la temperatura supera un umbral determinado o si el brillo supera un umbral. Tres iniciadores separados controlan cada una de estas situaciones, y los tres se incluirían en un flujo de select
.
Flujos anidados
En las automatizaciones complejas, los nodos de flujo de ejecución también se pueden anidar. Por ejemplo, es posible que tengas un flujo secuencial que ejecute un flujo paralelo.
Los nodos de DSL se pueden anidar y combinar de varias maneras para satisfacer tus necesidades específicas, según las restricciones que se describen en la siguiente tabla. La columna Builder vincula a la documentación del compilador de acceso seguro a tipos de Kotlin, que detalla lo que se permite usar en cada tipo de nodo.
Nodo | Puede contener el siguiente tipo de nodo y datos | Debe estar dentro de uno de los siguientes tipos de nodos |
---|---|---|
Starter | Expresión | Seleccionar, secuencial |
ManualStarter | Seleccionar, secuencial | |
StateReader | Expresión (por lo general, consta de un valor de atributo de rasgo) | Acción, condición |
Acción | Command, Entity, Expression | Paralelo, Seleccionar, Secuencial |
Secuencial | Paralelo, Seleccionar, Secuencial | |
Paralelo | Acción | Secuencial |
Afección | Expresión | Paralelo, secuencial |
Seleccionar | Condición, Secuencial, Activador, ManualStarter | Secuencial y debe ser el primer nodo del flujo |
DSL de automatización
En las APIs de Home, las automatizaciones se definen con el DSL de Automation (lenguaje específico del dominio). La DSL de Automation se implementa como un DSL de Kotlin (lenguaje específico del dominio), con compiladores de acceso seguro a tipos de Kotlin y está diseñada específicamente para definir plantillas de automatización.
Cuando se compila una automatización, los compiladores de Kotlin con seguridad de tipos generan clases de datos de Kotlin que luego se serializan en JSON de búfer de protocolo, que se usa para realizar llamadas a los servicios de automatización de Google.
El DSL de Automation simplifica y agiliza el proceso de creación de automatizaciones. Utiliza de forma nativa el mismo modelo de datos de los rasgos estándar Matter y los rasgos smart home que se incluyen en la API de Device.
El DSL de Automation también define la lógica de una automatización en términos de tipos de dispositivos abstractos, en lugar de instancias de dispositivos específicos ubicados en la casa de un usuario. Permite que el desarrollador proporcione parámetros de entrada que se pueden usar en el tiempo de ejecución para especificar instancias de dispositivos reales, así como otros valores de parámetros importantes.
La sintaxis de la DSL es similar a la de Kotlin y es igual de segura en cuanto a tipos, pero una automatización escrita en la DSL de Automation es más simple y concisa que la misma automatización escrita en Kotlin puro.
Ejemplo
A continuación, se muestra un ejemplo de automatización que enciende un dispositivo, escrito con el DSL de Automation:
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()) }
}
}
Esta automatización es muy básica: cuando se enciende device1
, una luz (el atributo onOff
cambia a true
), se envía el comando on()
para encender device2
.
La automatización usa un nodo sequential
, que indica que sus nodos se ejecutarán en orden secuencial.
Dentro del nodo sequential
, se encuentran nodos de comportamiento, como starter
, condition
y action
. El resultado del nodo starter
se asigna a una variable para usarla en el nodo condition
.