Концепции Android DSL

Это обзор основных концепций языка автоматизации DSL на Android.

Компоненты автоматизации

Система автоматизации состоит из следующих основных компонентов, которые обычно оцениваются в таком порядке:

  1. Запуск — определяет начальные условия, которые активируют автоматизацию, например, изменение характеристики. Автоматизация должна иметь запуск.
  2. Условие — любые дополнительные ограничения, которые необходимо оценить после активации автоматизации. Выражение в условии должно быть true , чтобы действия автоматизации могли быть выполнены.
  3. Действие — команды или обновления состояния, выполняемые при соблюдении всех условий.

Например, у вас может быть автоматизация, которая приглушает свет в комнате, когда в этой комнате включается телевизор в период между закатом и восходом солнца. В этом примере:

  1. Начало — Телевизор был включен, что означает изменение состояния параметра телевизора.
  2. Состояние — оценивается текущее время в доме, где находится телевизор.
  3. Действие — Свет в комнате, где находится телевизор, приглушен.

Автоматизация активируется при включении телевизора в комнате, но выполняется только при соблюдении условия «время находится между закатом и восходом солнца».

Помимо базовой структуры, автоматизации в API Home также содержат метаданные, такие как имя и описание , которые могут использоваться для их идентификации разработчиками и пользователями.

Узлы

В API Home логическая структура автоматизации состоит из узлов . Узлы — это абстрактные, многократно используемые единицы, представляющие поведение сущностей или потоки выполнения. Каждый узел может иметь входные переменные, а также выходные переменные, которые могут использоваться другими узлами.

Таблица: Типы узлов автоматизации
Узел Тип узла Реализация на Kotlin Описание
Стартер Поведенческий StarterNodeDsl Запускает автоматизацию при изменении состояния признака (любого атрибута).
StateReader Поведенческий StateReaderNodeDsl Считывает атрибут признака и позволяет получить его значение для использования в узлах условий.
Действие Поведенческий ActionNodeDsl Вызывает команду(ы) проверки свойства.
Последовательный Последовательность выполнения SequentialFlow Выполняет вложенные узлы действий последовательно. Это поведение выполнения по умолчанию.
Параллельный Последовательность выполнения ParallelFlow Выполняет вложенные узлы действий параллельно.
Состояние Последовательность выполнения ConditionNodeDsl Изменение хода выполнения программы может происходить в зависимости от результатов оценки логических выражений. Условия могут быть связаны с конкретным запуском (условия, специфичные для запуска) или быть глобальными (применяются ко всем запускам).
Выбирать Последовательность выполнения SelectFlow Позволяет активировать автоматизацию более чем одному запускающему объекту.
Выражение Ценить Expression Может представлять собой значение атрибута признака, константу или литерал, и в результате должно принимать значение списка, числа, логического значения или строки.

Поведенческие узлы

Такие узлы, как «стартеры» и «действия», являются поведенческими узлами. «Стартеры» активируют автоматизацию на основе изменений атрибутов устройства. «Действия» отдают команды устройству или обновляют атрибуты.

Поведенческие узлы обычно привязаны к характеристикам устройства и состоянию выходных характеристик, которые используются в качестве входных данных для других узлов.

Узлы потока выполнения

Некоторые узлы представляют потоки выполнения, например, последовательные и параллельные. Каждый из этих узлов содержит поведенческие узлы, определяющие автоматизацию.

Например, последовательный поток может содержать узлы, которые выполняются в последовательном порядке. Как правило, это узел запуска, узел условия и узел действия.

Последовательные потоки выполнения
Рисунок 1: Последовательный поток автоматизации

В параллельном потоке может одновременно выполняться несколько узлов действий, например, одновременное включение нескольких источников света. Узлы, следующие за параллельным потоком, не начнут выполняться до тех пор, пока не завершатся все ветви параллельного потока.

Параллельные потоки выполнения
Рисунок 2: Параллельный процесс автоматизации

Другой тип потока выполнения — это поток условий , который может изменять поток выполнения в зависимости от оценки выражения.

Например, у вас может быть автоматизированная задача, которая выполняет действие в зависимости от того, наступила ли ночь. Узел условия проверяет время суток, а затем следует соответствующему пути выполнения в зависимости от этой оценки.

Поток условий
Рисунок 3: Схема выполнения условий

Использование конструкции `select flow` полезно, когда вам нужно, чтобы несколько элементов запускали вашу автоматизацию. Если вы объедините два или более элементов запуска в select конструкцию, любой из них сможет запустить автоматизацию.

Например, можно написать автоматизацию, которая опускает жалюзи на закате, если температура поднимается выше определенного порога или если яркость превышает пороговое значение. Для каждого из этих сценариев будут использоваться три отдельных запускаемых процесса, и все три будут объединены в поток select .

Выберите поток
Рисунок 4: Выбор потока

Вложенные потоки

В сложных системах автоматизации узлы выполнения потока могут быть вложенными. Например, у вас может быть последовательный поток, который выполняет параллельный поток.

Вложенные потоки выполнения
Рисунок 5: Вложенные потоки выполнения

Узлы DSL можно вкладывать и комбинировать различными способами в соответствии с вашими конкретными потребностями, согласно ограничениям, изложенным в следующей таблице. Столбец Builder содержит ссылку на документацию по типобезопасному построителю Kotlin, в которой подробно описано, что разрешено использовать в каждом типе узла.

Таблица: Способы объединения узлов
Узел Может содержать следующие типы узлов и данные. Должен находиться в одном из следующих типов узлов.
Стартер Выражение Выбрать, Последовательный
Ручной запуск Выбрать, Последовательный
StateReader Выражение (обычно состоящее из значения атрибута признака) Действие, состояние
Действие Команда, Сущность, Выражение Параллельный, выборочный, последовательный
Последовательный Параллельный, выборочный, последовательный
Параллельный Действие Последовательный
Состояние Выражение Параллельный, последовательный
Выбирать Состояние, Последовательный, Стартер, Ручной Стартер Последовательный, и должен быть первым узлом в потоке.

Автоматизация DSL

В API Home автоматизация определяется с помощью предметно-ориентированного языка автоматизации (Automation DSL). Automation DSL реализован как предметно-ориентированный язык Kotlin (Kotlin DSL) , использующий типобезопасные построители Kotlin и специально разработанный для определения шаблонов автоматизации.

При компиляции автоматизации типобезопасные построители Kotlin генерируют классы данных Kotlin, которые затем сериализуются в JSON-файлы протокола Protocol Buffer, используемые для вызовов к сервисам автоматизации Google.

Язык программирования Automation DSL упрощает и оптимизирует процесс создания автоматизаций. Он использует ту же модель данных , что и стандартные характеристики Matter и характеристики smart home , представленные в Device API.

Язык описания автоматизации (Automation DSL) также определяет логику автоматизации с помощью абстрактных типов устройств, а не конкретных экземпляров устройств, расположенных в доме пользователя. Это позволяет разработчику предоставлять входные параметры, которые могут использоваться во время выполнения для указания фактических экземпляров устройств, а также других важных значений параметров.

Синтаксис DSL похож на синтаксис Kotlin и также типобезопасен, но автоматизация, написанная на Automation DSL, проще и лаконичнее, чем та же автоматизация, написанная на чистом Kotlin.

Пример

Ниже приведён пример автоматизации, включающей устройство, написанный с использованием языка автоматизации Automation 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 2.

В системе автоматизации используется sequential узел, что означает, что его узлы будут выполняться в последовательном порядке.

Внутри sequential узла находятся поведенческие узлы, такие как starter , condition и action . Выходной сигнал узла starter присваивается переменной для использования в узле condition .