Use o guia a seguir para entender como vários nós da DSL de automação podem ser usados para criar uma automação.
Toda a DSL de automação é colocada em um único nó automation. O nó
automation forma o limite entre o contexto externo da linguagem Kotlin
e o contexto da DSL incorporada.
Fluxo sequencial
O fluxo sequencial é o tipo padrão de fluxo de automação.
Confira um modelo muito básico de DSL de automação que usa um fluxo sequencial composto por uma ativação, uma condição e uma ação:
import com.google.home.automation.action
import com.google.home.automation.automation
import com.google.home.automation.condition
import com.google.home.automation.sequential
import com.google.home.automation.starter
...
automation {
sequential {
starter<_>(...)
condition {...}
action {...}
}
}
Isso pode ser refinado adicionando mais nós.
Starter
Os nós de ativação definem as circunstâncias iniciais que ativam uma automação. Por
exemplo, uma mudança no estado ou no valor. Uma automação precisa ter pelo menos uma
ativação. Caso contrário, ela não será validada. Para adicionar mais de uma ativação a uma automação, use um nó select.
Iniciador com base no atributo de característica
Ao declarar um nó inicial baseado em um atributo de trait, especifique:
- o dispositivo
- o tipo de dispositivo ao qual o atributo pertence
- o trait
starter<_>(thermostat, TemperatureSensorDevice, TemperatureMeasurement)
O parâmetro de tipo de dispositivo é obrigatório porque permite especificar qual tipo de dispositivo
dentro de um dispositivo a automação aborda. Por exemplo, um dispositivo pode ser
composto por um
FanDevice
e um
HeatingCoolingUnitDevice,
que contêm o atributo
OnOff. Ao especificar o tipo de dispositivo, não há ambiguidade sobre qual parte dele
aciona a automação.
Ativação com base em evento
Ao declarar um nó de ativação com base em um evento, especifique:
- o dispositivo
- o tipo de dispositivo ao qual o atributo pertence
- o evento
starter<_>(doorBell, GoogleDoorbellDevice, DoorbellPressed)
Ativação com base em uma estrutura e um evento, com parâmetros
Alguns eventos podem ter parâmetros, que também precisam ser incluídos na ativação.
Por exemplo, esta ativação usa o
ScheduledTimeEvent do atributo Time para ativar a automação às 7h:
val earlyMorning = starter<_>(structure, Time.ScheduledTimeEvent) {
parameter(Time.ScheduledTimeEvent.clockTime(
LocalTime.of(7, 0, 0, 0)))
}
Acionador com base no clima
É possível especificar condições climáticas atuais ou previstas em uma ativação usando o atributo Clima:
val weatherState = starter<_>(structure, trait = Weather)
Consulte Fechar as persianas se houver previsão de chuva na página Exemplos de automações.
Início manual
Um acionador manual é um tipo especial de acionador que permite ao usuário executar manualmente a automação.
Ao declarar uma ativação manual:
- Não especifique um atributo ou tipo de dispositivo.
- Forneça um elemento da interface que chame
Automation.execute().
Ao colocar uma ativação manual em um fluxo select com outra ativação, a
manual substitui a outra:
select {
manualStarter()
starter<_>(thermostat, TemperatureSensorDevice, TemperatureMeasurement)
}
Todos os nós condition que seguem uma ativação manual serão avaliados
e poderão bloquear a execução da automação, dependendo da expressão
condition.
Uma maneira de estruturar a automação para que os nós condition não bloqueiem uma
automação ativada com uma ativação manual é colocar a outra ativação
em um fluxo sequencial separado com o condition:
automation_graph {
sequential {
select {
sequential {
starter<_>(...)
condition {...}
}
sequential {
manualStarter()
}
}
action {...}
}
}
Fazer referência ao valor de um atributo
Para usar o valor de um atributo em uma expressão, use a sintaxe a seguir.
Com um stateReader:
val time = stateReader<_>(structure, Structure, Time)
val currTime = time.currentTime
Com um starter:
val starterNode = starter<_>(device1, LaundryWasherDevice, OnOff)
condition() {
expression = starterNode.onOff equals true
}
Nós e expressões de condição
Um nó de condição representa um ponto de decisão que determina se a
automação continua ou não. Uma automação pode ter vários nós condition.
Se a expressão de qualquer nó condition for avaliada como false, a execução de toda a automação será encerrada.
Em um nó condition, é possível combinar vários critérios de condição usando
vários operadores, desde que a expressão
seja avaliada como um único
valor booleano. Se o valor resultante for true, a condição será atendida e a
automação continuará a execução do próximo nó. Se for false, a automação
vai parar de ser executada nesse ponto.
As expressões são formadas de maneira semelhante às expressões em Kotlin e podem conter valores primitivos, como números, caracteres, strings e booleanos, além de valores de tipo enumerado. Agrupar subexpressões com parênteses permite controlar a ordem em que elas são avaliadas.
Veja um exemplo de condition que combina várias subexpressões em uma
única expressão:
condition() {
val expr1 = starterNode.lockState equals DlLockState.Unlocked
val expr2 = stateReaderNode.lockState equals true
val expr3 = occupancySensingDevice.occupied notEquals 0
val expr4 = timeStateReaderNode
.currentTime
.between(
timeStateReaderNode.sunsetTime,
timeStateReaderNode.sunriseTime)
expression = (expr1 and expr2) or (expr3 and expr4)
}
É possível referenciar o valor de um atributo acessado por um inicializador:
val starterNode = starter<_>(device, OnOff)
condition() { expression = starterNode.onOff equals true }
stateReader
A outra maneira de referenciar valores de atributos de traço em um nó condition é com
um nó stateReader.
Para fazer isso, primeiro capture o valor do atributo de trait em um nó stateReader. Um
stateReader usa o structure e o atributo como argumentos:
import com.google.home.automation.stateReader
...
val filterMonitoringState = stateReader<_>(structure, ActivatedCarbonFilterMonitoring)
Em seguida, faça referência ao stateReader no nó condition:
condition() {
expression =
filterMonitoringState.changeIndication
.equals(ChangeIndicationEnum.Warning)
}
Usando comparação e
operadores lógicos, vários
stateReaders podem ser usados em um nó condition:
val armState = stateReader<_>(doorLock, DoorLockDevice, ArmDisarm )
val doorLockState = stateReader<_>(doorLock, DoorLockDevice, DoorLock)
condition() {
expression =
(armState.armState equals true)
and
(doorLockState.lockState equals true)
}
Duração da condição
Além de uma expressão booleana em uma condição, é possível especificar um período em que a expressão precisa ser verdadeira para executar a automação. Por exemplo, é possível definir uma condição que só é acionada se uma luz estiver acesa por dez minutos.
condition {
expression(lightStateReader.onOff == true)
forDuration(Duration.ofMinutes(10))
}
A duração pode variar de 5 segundos a 24 horas.
Nós de ação
O nó de ação é onde o trabalho da automação ocorre.
Neste exemplo, a ação invoca o comando
broadcast()
do atributo
AssistantBroadcast:
action(device, SpeakerDevice) {
command(AssistantBroadcast.broadcast("Intruder detected!"))
}
Declarações de importação
Ao desenvolver automações, nem sempre é óbvio como importar vários elementos das APIs do Google Home para seu código.
Os atributos de trait são importados do objeto Companion do trait:
import com.google.home.matter.standard.OnOff.Companion.onOff
As estruturas de dados definidas por uma característica são importadas da classe de característica com o nome que termina em "-Trait":
import com.google.home.matter.standard.MediaPlaybackTrait.PlaybackStateEnum
Os comandos de trait são importados do objeto Companion do trait:
import com.google.home.matter.standard.Thermostat.Companion.setTemperatureSetpointHold