Z tego przewodnika dowiesz się, jak za pomocą różnych węzłów Automation DSL tworzyć automatyzacje.
Cały język DSL automatyzacji znajduje się w jednym węźle automation
. Węzeł
automation
stanowi granicę między zewnętrznym kontekstem języka Swift a osadzonym kontekstem DSL.
Przepływ sekwencyjny
Przepływ sekwencyjny to domyślny typ przepływu automatyzacji.
Oto bardzo prosty szablon DSL automatyzacji, który wykorzystuje sekwencyjny przepływ składający się z elementu początkowego, warunku i działania:
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
starter(...)
condition {...}
action {...}
}
Możesz to poprawić, dodając kolejne węzły.
Początkujący
Węzły początkowe określają początkowe okoliczności, które aktywują automatyzację. Na przykład zmiana stanu lub wartości. Automatyzacja musi mieć co najmniej 1 element początkowy, w przeciwnym razie nie przejdzie weryfikacji. Aby dodać do automatyzacji więcej niż jeden element początkowy, musisz użyć węzła select
.
Starter na podstawie atrybutu cechy
Podczas deklarowania węzła początkowego opartego na atrybucie cechy podaj:
- urządzenie
- typ urządzenia, do którego należy cecha;
- cecha
starter(
thermostat,
Matter.TemperatureSensorDeviceType.self,
Matter.TemperatureMeasurementTrait.self
)
Parametr typu urządzenia jest wymagany, ponieważ umożliwia określenie, do którego typu urządzenia w ramach urządzenia odnosi się automatyzacja. Urządzenie może się np. składać z FanDeviceType
i HeatingCoolingUnitDeviceType
, z których oba zawierają cechę OnOffTrait
. Określenie typu urządzenia eliminuje niejasności co do tego, która część urządzenia wywołuje automatyzację.
Lista startowa na podstawie zdarzenia
Podczas deklarowania węzła początkowego opartego na zdarzeniu określ:
- urządzenie
- typ urządzenia, do którego należy cecha;
- wydarzenie,
starter(
doorbell,
Google.GoogleDoorbellDeviceType.self,
Google.DoorbellPressTrait.DoorbellPressedEvent
)
Wstępna wersja oparta na strukturze i zdarzeniu z parametrami
Niektóre zdarzenia mogą mieć parametry, więc te parametry też muszą być uwzględnione w wersji początkowej.
Na przykład ten inicjator używa TimeTrait
ScheduledEvent
do aktywowania automatyzacji o 7:00:
typealias TimeTrait = Google.TimeTrait
let earlyMorning = starter(
structure,
TimeTrait.ScheduledEvent.self
) {
TimeTrait.ScheduledEvent.clockTime(TimeOfDay(hours: 7, minutes: 0))
}
Rozrusznik ręczny
Ręczny wyzwalacz to specjalny typ wyzwalacza, który umożliwia użytkownikowi ręczne uruchamianie automatyzacji.
Podczas deklarowania ręcznego startera:
- Nie określaj cechy ani typu urządzenia.
- Podaj element interfejsu, który wywołuje funkcję
Automation.execute()
.
Jeśli umieścisz ręczny początek w select
przepływie razem z innym początkiem, ręczny początek zastąpi ten drugi:
select {
manualStarter()
starter(
thermostat,
Matter.TemperatureSensorDeviceType.self,
Matter.TemperatureMeasurementTrait.self
)
}
Pamiętaj, że wszystkie condition
węzły następujące po ręcznym węźle początkowym zostaną sprawdzone i mogą zablokować wykonanie automatyzacji w zależności od condition
wyrażenia.
Jednym ze sposobów skonstruowania automatyzacji tak, aby węzły condition
nie blokowały automatyzacji aktywowanej za pomocą ręcznego startera, jest umieszczenie innego startera w osobnym przepływie sekwencyjnym wraz z węzłem condition
:
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
select {
sequential {
starter(...)
condition {...}
}
sequential {
manualStarter()
}
}
action {...}
}
Odwoływanie się do wartości atrybutu
Aby użyć w wyrażeniu wartości atrybutu, zastosuj tę składnię:
W przypadku stateReader
:
typealias TimeTrait = Google.TimeTrait
let time = stateReader(structure, TimeTrait.self)
time
let currTime = time.currentTime
W przypadku starter
:
typealias LaundryWasherDeviceType = Matter.LaundryWasherDeviceType
typealias OnOffTrait = Google.OnOffTrait
let starterNode = starter(device1, LaundryWasherDeviceType.self, OnOffTrait.self)
starterNode
condition {
starterNode.onOff.equals(true)
}
Węzły warunków i wyrażenia
Węzeł warunku reprezentuje punkt decyzyjny, który określa, czy automatyzacja będzie kontynuowana. Automatyzacja może mieć wiele węzłów condition
.
Jeśli wyrażenie dowolnego węzła condition
przyjmie wartość false
, wykonanie całej automatyzacji zostanie zakończone.
W węźle condition
możesz łączyć wiele kryteriów warunku za pomocą różnych operatorów, o ile wyrażenie daje w wyniku pojedynczą wartość logiczną. Jeśli wynikowa wartość to true
, warunek jest spełniony, a automatyzacja kontynuuje wykonywanie następnego węzła. Jeśli jest to false
, automatyzacja przestaje działać w tym momencie.
Wyrażenia są tworzone podobnie jak wyrażenia w Swift i mogą zawierać wartości pierwotne, takie jak liczby, znaki, ciągi tekstowe i wartości logiczne, a także wartości wyliczeniowe. Grupowanie podwyrażeń za pomocą nawiasów pozwala kontrolować kolejność ich obliczania.
Oto przykład condition
, który łączy wiele podwyrażeń w jedno wyrażenie:
condition {
let exp1 = starterNode.lockState.equals(.unlocked)
let exp2 = stateReaderNode.lockState.equals(true)
let exp3 = occupancySensingDevice.occupied.notEquals(0)
(exp1.and(exp2)).or(exp3)
}
Możesz odwoływać się do wartości cechy, do której dostęp uzyskano za pomocą elementu początkowego:
typealias OnOffTrait = Matter.OnOffTrait
let starterNode = starter(device, OnOffTrait.self)
starterNode
condition {
starterNode.onOff.equals(true)
}
val starterNode = starter<_>(device, OnOff)
condition() { expression = starterNode.onOff equals true }
stateReader
Innym sposobem odwoływania się do wartości atrybutów cech w węźle condition
jest użycie węzła stateReader
.
Aby to zrobić, najpierw przechwyć wartość atrybutu cechy w węźle stateReader
. Funkcja stateReader
przyjmuje jako argumenty structure
i cechę:
typealias ActivatedCarbonFilterMonitoringTrait = Matter.ActivatedCarbonFilterMonitoringTrait
let filterMonitoringState = stateReader(structure, ActivatedCarbonFilterMonitoringTrait.self)
Następnie odwołaj się do stateReader
w węźle condition
:
condition {
filterMonitoringState.changeIndication.equals(.warning)
}
Za pomocą operatorów porównania i logicznych w węźle condition
można użyć wielu operatorów stateReaders
:
typealias ArmDisarm = Google.ArmDisarmTrait
typealias DoorLockDevice = Matter.DoorLockDeviceType
typealias DoorLock = Matter.DoorLockTrait
let armState = stateReader(doorLock, DoorLockDevice.self, ArmDisarm )
let doorLockState = stateReader(doorLock, DoorLockDevice.self, DoorLock)
armState
doorLockState
condition {
let exp1 = armState.armState
let exp2 = doorLockState.lockState
exp1.and(exp2)
}
Czas trwania warunku
Oprócz wyrażenia logicznego w warunku możesz określić przedział czasu, w którym wyrażenie musi być prawdziwe, aby uruchomić automatyzację. Możesz na przykład zdefiniować warunek, który będzie aktywowany tylko wtedy, gdy światło jest włączone od 10 minut.
condition(for: .seconds(600)) {
lightStateReader.onOff.equals(true)
}
Może to być od 1 do 30 minut.
Węzły działań
W węźle działania odbywa się praca automatyzacji.
W tym przykładzie działanie wywołuje polecenie AssistantBroadcastTrait
broadcast()
:
action(speaker, SpeakerDeviceType.self) {
Google.AssistantBroadcastTrait.broadcast(msg: "Oven Cycle Complete")
}