Z tego przewodnika dowiesz się, jak można wykorzystać różne węzły języka DSL automatyzacji do tworzenia automatyzacji.
Cały DSL automatyzacji jest umieszczony w jednym węźle automation. Węzeł automation tworzy granicę między zewnętrznym kontekstem języka Swift a wbudowanym kontekstem DSL.
Przepływ sekwencyjny
Przepływ sekwencyjny jest domyślnym typem przepływu automatyzacji.
Oto bardzo prosty szablon DSL automatyzacji, który wykorzystuje przepływ sekwencyjny składający się z elementu inicjującego, warunku i działania:
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
starter(...)
condition {...}
action {...}
}
Można go ulepszyć, dodając kolejne węzły.
Starter
Węzły poleceń inicjujących określają początkowe okoliczności, które aktywują automatyzację. Może to być na przykład zmiana stanu lub wartości. Automatyzacja musi mieć co najmniej 1 element inicjujący, inaczej nie przejdzie weryfikacji. Aby dodać do automatyzacji więcej niż 1 element inicjujący, musisz użyć węzła select.
Element inicjujący na podstawie atrybutu cechy
Podczas deklarowania węzła początkowego opartego na atrybucie cechy określ:
- 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ż pozwala określić, którego typu urządzenia dotyczy automatyzacja. Na przykład urządzenie może składać się z FanDeviceType i HeatingCoolingUnitDeviceType, które zawierają cechę OnOffTrait. Dzięki określeniu typu urządzenia nie ma wątpliwości, która część urządzenia uruchamia automatyzację.
Element inicjujący na podstawie zdarzenia
Podczas deklarowania węzła początkowego opartego na zdarzeniu podaj:
- urządzenie
- typ urządzenia, do którego należy cecha;
- wydarzenie,
starter(
doorbell,
Google.GoogleDoorbellDeviceType.self,
Google.DoorbellPressTrait.DoorbellPressedEvent
)
Element inicjujący oparty na strukturze i zdarzeniu, z parametrami
Niektóre zdarzenia mogą mieć parametry, więc te parametry również muszą być uwzględnione w uruchamianiu.
Na przykład to polecenie inicjujące używa ScheduledEvent urządzenia TimeTrait, aby aktywować automatyzację o 7:00:
typealias TimeTrait = Google.TimeTrait
let earlyMorning = starter(
structure,
TimeTrait.ScheduledEvent.self
) {
TimeTrait.ScheduledEvent.clockTime(TimeOfDay(hours: 7, minutes: 0))
}
Starter na podstawie pogody
Możesz określić bieżące lub prognozowane warunki pogodowe w uruchamianiu, używając cechy Pogoda:
let weatherState = starter<_>(structure, trait = Weather)
Zobacz Zamykanie rolet, gdy prawdopodobnie będzie padać na stronie Przykładowe automatyzacje.
Uruchamianie ręczne
Warunek inicjujący ręcznie to specjalny typ warunku inicjującego, który umożliwia użytkownikowi ręczne uruchomienie automatyzacji.
Podczas deklarowania ręcznego elementu inicjującego:
- Nie podawaj cechy ani typu urządzenia.
- Udostępnij element interfejsu, który wywołuje metodę
Automation.execute().
Jeśli umieścisz ręczny element inicjujący w przepływie select wraz z innym elementem inicjującym, ręczny element inicjujący zastąpi ten drugi:
select {
manualStarter()
starter(
thermostat,
Matter.TemperatureSensorDeviceType.self,
Matter.TemperatureMeasurementTrait.self
)
}
Pamiętaj, że wszystkie węzły condition po elemencie inicjującym ręcznie zostaną ocenione i mogą zablokować wykonanie automatyzacji, w zależności od wyrażenia condition.
Jednym ze sposobów na skonfigurowanie automatyzacji tak, aby węzły condition nie blokowały automatyzacji aktywowanej za pomocą ręcznego aktywatora, jest umieszczenie drugiego aktywatora w osobnym przepływie sekwencyjnym wraz z jego condition:
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
select {
sequential {
starter(...)
condition {...}
}
sequential {
manualStarter()
}
}
action {...}
}
Odwoływanie się do wartości atrybutu
Aby użyć wartości atrybutu w wyrażeniu, użyj tej 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 i wyrażenia warunku
Węzeł warunku reprezentuje punkt decyzyjny, który określa, czy automatyzacja ma być kontynuowana. Automatyzacja może mieć wiele węzłów condition.
Jeśli wyrażenie dowolnego węzła condition zostanie ocenione jako false, wykonywanie całej automatyzacji zostanie zakończone.
W węźle condition możesz łączyć wiele kryteriów warunków za pomocą różnych operatorów, o ile wyrażenie daje 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 języku Swift i mogą zawierać wartości podstawowe, takie jak liczby, znaki, ciągi znaków i wartości logiczne, a także wartości typu wyliczeniowego. Grupowanie podwyrażeń za pomocą nawiasów pozwala kontrolować kolejność ich oceny.
Oto przykład condition, który łączy kilka 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łać się do wartości cechy, do której dostęp uzyskano za pomocą elementu inicjującego:
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 operatorów logicznych można użyć wielu stateReaders w węźle condition:
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 stanu
Oprócz wyrażenia logicznego w warunku możesz określić przedział czasu, w którym wyrażenie musi być prawdziwe, aby automatyzacja została uruchomiona. Możesz na przykład zdefiniować warunek, który będzie aktywowany tylko wtedy, gdy światło będzie włączone przez 10 minut.
condition(for: .seconds(600)) {
lightStateReader.onOff.equals(true)
}
Czas trwania może wynosić od 1 do 30 minut.
Węzły działań
Węzeł działania to miejsce, w którym odbywa się praca automatyzacji.
W tym przykładzie działanie wywołuje polecenie broadcast() narzędzia AssistantBroadcastTrait:
action(speaker, SpeakerDeviceType.self) {
Google.AssistantBroadcastTrait.broadcast(msg: "Oven Cycle Complete")
}