Z tego przewodnika dowiesz się, jak tworzyć automatyzacje za pomocą różnych węzłów automatyzacji DSL.
Cała automatyzacja DSL jest umieszczana w pojedynczym węźle automation
. automation
stanowi granicę między zewnętrznym kontekstem języka Swift a osadzonym kontekstem DSL.
Sekwencyjny
Sekwencyjny to domyślny typ przepływu automatyzacji.
Oto bardzo prosty szablon automatyzacji DSL, który używa sekwencyjnego przepływu, składającego się z elementu startowego, warunku i działania:
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
starter(...)
condition {...}
action {...}
}
Możesz to doprecyzować, dodając dodatkowe węzły.
Początkujący
Początkowe węzły definiują początkowe okoliczności, które aktywują automatyzację. na przykład zmiana stanu lub wartości. Automatyzacja musi mieć co najmniej 1 element inicjujący, w przeciwnym razie nie przejdzie walidacji. Aby dodać do automatyzacji więcej niż 1 element startowy, musisz użyć węzła select
.
Starter na podstawie atrybutu cech
Podczas deklarowania węzła startowego opartego na atrybucie cechy podaj:
- urządzenie
- typ urządzenia, do którego należy cecha;
- cechy
starter(
thermostat,
Matter.TemperatureSensorDeviceType.self,
Matter.TemperatureMeasurementTrait.self
)
Parametr device type jest wymagany, ponieważ pozwala określić, który typ urządzenia ma być obsługiwany przez automatyzację. Na przykład urządzenie może składać się z urządzenia FanDeviceType
i urządzenia HeatingCoolingUnitDeviceType
, z których każde zawiera cechę OnOffTrait
. Określając typ urządzenia, usuwasz niejednoznaczność dotyczącą tego, która część urządzenia uruchamia automatyzację.
Starter na podstawie zdarzenia
Podczas deklarowania węzła startowego 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
)
Starter oparty na strukturze i zdarzeniu z parametrami
Niektóre zdarzenia mogą mieć parametry, więc te parametry muszą też zostać uwzględnione w starterze.
Na przykład to starter używa ScheduledEvent
w TimeTrait
, aby aktywować automatyzację o 7:00 rano:
typealias TimeTrait = Google.TimeTrait
let earlyMorning = starter(
structure,
TimeTrait.ScheduledEvent.self
) {
TimeTrait.ScheduledEvent.clockTime(TimeOfDay(hours: 7, minutes: 0))
}
Ręczne uruchamianie
Rozpoczęcie ręczne to specjalny typ, który umożliwia użytkownikowi ręczne uruchamianie automatyzacji.
Podczas deklarowania ręcznego uruchamiania:
- Nie określaj cech ani typu urządzenia.
- Podaj element interfejsu, który wywołuje funkcję
Automation.execute()
.
Gdy w sekwencji select
umieścisz ręczny początek razem z innym początkiem, ręczny początek zastąpi inny początek:
select {
manualStarter()
starter(
thermostat,
Matter.TemperatureSensorDeviceType.self,
Matter.TemperatureMeasurementTrait.self
)
}
Pamiętaj, że wszystkie węzły condition
po ręcznym starterze zostaną ocenione i mogą zablokować wykonanie automatyzacji, w zależności od wyrażenia condition
.
Jednym ze sposobów ustrukturyzowania automatyzacji tak, aby węzły condition
nie blokowały automatyzacji aktywowanej za pomocą ręcznego startera, jest umieszczenie drugiego startera w osobnym sekwencyjnym przepływie 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 warunków
Węzeł warunku reprezentuje punkt podejmowania decyzji, który decyduje, czy automatyzacja ma być kontynuowana. Automatyzacja może mieć wiele węzłów condition
.
Jeśli wyrażenie dowolnego węzła condition
ma wartość false
, kończy się wykonywanie całej automatyzacji.
W węźle condition
możesz łączyć wiele warunków za pomocą różnych operatorów, o ile wyrażenie daje w wyniku jedną wartość logiczną. Jeśli wynikowa wartość to true
, warunek jest spełniony i automatyzacja kontynuuje wykonywanie następnego węzła. Jeśli jest to false
, automatyzacja przestaje się w tym momencie wykonywać.
Wyrażenia są tworzone podobnie jak w Swift i mogą zawierać wartości proste takie jak liczby, znaki, ciągi tekstowe i wartości logiczne, a także wartości typu Enum. Grupowanie podwyrażeń za pomocą nawiasów pozwala kontrolować kolejność ich obliczania.
Oto przykład condition
, który łączy wiele podwyrażeń w jeden 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)
}
Wartość atrybutu możesz pobrać za pomocą startera:
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 na odniesienie się do wartości atrybutów cech w węźle condition
jest użycie węzła stateReader
.
Aby to zrobić, najpierw uchwyć 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łuj się do elementu stateReader
w węźle condition
:
condition {
filterMonitoringState.changeIndication.equals(.warning)
}
Za pomocą operatorów porównywania i operatorów logicznych w węźle condition
można użyć wielu elementó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 automatyzacja mogła się wykonać. Możesz na przykład zdefiniować warunek, który będzie się aktywować tylko wtedy, gdy światło było 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łania
W węźle działania odbywa się automatyzacja.
W tym przykładzie działanie wywołuje polecenie AssistantBroadcastTrait
:
broadcast()
action(speaker, SpeakerDeviceType.self) {
Google.AssistantBroadcastTrait.broadcast(msg: "Oven Cycle Complete")
}