Bạn có thể dùng DSL tự động hoá để tạo các quy trình tự động hoá phức tạp hơn những quy trình được thảo luận trong Hướng dẫn về DSL – quy trình tự động hoá cơ bản trên iOS.
Tuần tự với nhiều hành động
Một quy trình tự động có thể thực hiện nhiều việc. Ví dụ: thay vì một nút action, bạn có thể có nhiều nút action chạy theo thứ tự tuần tự:
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
starter(...)
condition {...}
action {...}
action {...}
action {...}
}
Tuần tự với nhiều hành động song song
Nếu bạn đặt nhiều nút action trong một nút parallel, thì các hành động sẽ thực thi đồng thời.
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
starter(...)
condition {...}
parallel {
action {...}
action {...}
action {...}
}
}
Nếu có các nút action trong nút sequential xuất hiện sau nút parallel, thì các nút đó sẽ đợi cho đến khi tất cả các nút trong nút parallel thực thi xong.
Thực thi có điều kiện
Theo mặc định, một quy trình tự động hoá sẽ thực thi các nút theo tuần tự hoặc song song. Nếu bạn cần logic phân nhánh có điều kiện (thực thi các hành động hoặc đường dẫn khác nhau dựa trên điều kiện thời gian chạy), hãy sử dụng câu lệnh if-then-else, được tạo bằng các khối DSL luồng điều khiển có điều kiện: ifThen, elseIf và orElse.
Mặc dù nút condition tiêu chuẩn kiểm soát toàn bộ quy trình tự động hoá (nếu điều kiện được đánh giá là false, thì quy trình tự động hoá sẽ chấm dứt thực thi ngay lập tức), nhưng các khối ifThen cho phép phân nhánh luồng điều khiển:
conditionnode: Dừng thực thi toàn bộ quy trình tự động hoá (hoặc đường dẫn thực thi hiện tại) nếu biểu thức làfalse.ifThen/elseIf/orElse: Đánh giá các điều kiện theo thứ tự. Nếu một điều kiện làfalse, thì quá trình thực thi sẽ chuyển sang nhánhelseIftiếp theo, nhánh dự phòngorElsehoặc tiếp tục đến các nút tiếp theo trong quy trình tự động hoá nếu không có điều kiện nào được đáp ứng.
Thực hiện một hành động dựa trên một điều kiện
Khối ifThen đánh giá một biểu thức có điều kiện. Nếu biểu thức cho kết quả là true, thì các hành động hoặc nút DSL lồng trong khối sẽ được thực thi. Nếu điều kiện được đánh giá là false, thì các hành động sẽ bị bỏ qua và quy trình tự động hoá sẽ tiếp tục đến các nút tiếp theo trong quy trình tuần tự.
Bạn có thể sử dụng một khối ifThen độc lập khi chỉ muốn thực hiện một hành động có điều kiện mà không chặn hoặc chấm dứt các nút tiếp theo trong quy trình tự động hoá:
// When a door opens, turn on the light only if it is off,
// and always broadcast an announcement.
typealias ContactSensorDevice = Matter.ContactSensorDeviceType
typealias BooleanStateTrait = Matter.BooleanStateTrait
typealias DimmableLightDevice = Matter.DimmableLightDeviceType
typealias OnOffTrait = Matter.OnOffTrait
automation {
let contactState = starter(
contactSensor,
ContactSensorDevice.self,
BooleanStateTrait.self
)
let lightState = stateReader(
light,
DimmableLightDevice.self,
OnOffTrait.self
)
contactState
lightState
condition {
// Door opened (contact sensor open)
contactState.stateValue.equals(false)
}
// Conditionally turn on the light if it's off
ifThen(lightState.onOff.equals(false)) {
action(light, DimmableLightDevice.self) {
OnOffTrait.on()
}
}
// Continue executing subsequent actions in the sequential flow
action(structure) {
Google.AssistantBroadcastTrait.broadcast(msg: "The door was opened.")
}
}
Thực hiện các hành động khác nhau dựa trên một điều kiện
Để thực thi một tập hợp hành động khi điều kiện là đúng và một tập hợp hành động thay thế khi điều kiện là sai, hãy liên kết khối .orElse { ... } không bắt buộc sau ifThen(...) { ... }:
// When the door is unlocked, turn on the entryway light if it is off;
// otherwise, broadcast a welcome message.
typealias DoorLockDevice = Matter.DoorLockDeviceType
typealias DoorLockTrait = Matter.DoorLockTrait
typealias DimmableLightDevice = Matter.DimmableLightDeviceType
typealias OnOffTrait = Matter.OnOffTrait
automation {
let doorLockEvent = starter(
doorLock,
DoorLockDevice.self,
DoorLockTrait.LockOperationEvent.self
)
let lightState = stateReader(
light,
DimmableLightDevice.self,
OnOffTrait.self
)
doorLockEvent
lightState
condition {
doorLockEvent.lockOperationType.equals(.unlock)
}
ifThen(lightState.onOff.equals(false)) {
action(light, DimmableLightDevice.self) {
OnOffTrait.on()
}
}.orElse {
action(structure) {
Google.AssistantBroadcastTrait.broadcast(msg: "Welcome home!")
}
}
}
Kết hợp nhiều điều kiện theo trình tự
Bạn có thể liên kết một hoặc nhiều khối .elseIf(...) { ... } không bắt buộc để đánh giá nhiều điều kiện theo trình tự. Nhánh đầu tiên có điều kiện được đánh giá là true sẽ được thực thi và tất cả các nhánh còn lại sẽ bị bỏ qua. Nếu không có điều kiện nào được đánh giá là true, thì một khối .orElse { ... } không bắt buộc sẽ thực thi (nếu được cung cấp):
// Adjust climate controls based on room temperature changes.
typealias TemperatureSensorDeviceType = Matter.TemperatureSensorDeviceType
typealias TemperatureMeasurementTrait = Matter.TemperatureMeasurementTrait
typealias ThermostatDeviceType = Matter.ThermostatDeviceType
typealias SimplifiedThermostatTrait = Google.SimplifiedThermostatTrait
typealias FanDeviceType = Matter.FanDeviceType
typealias OnOffTrait = Matter.OnOffTrait
automation {
let tempStarter = starter(
tempSensor,
TemperatureSensorDeviceType.self,
TemperatureMeasurementTrait.self
)
tempStarter
// If temperature is high (>= 28°C / 2800 mC), switch thermostat to Cool mode
ifThen(tempStarter.measuredValue.greaterThanOrEquals(2800)) {
action(thermostat, ThermostatDeviceType.self) {
SimplifiedThermostatTrait.setSystemMode(systemMode: .cool)
}
}.elseIf(tempStarter.measuredValue.lessThan(1800)) {
// If temperature is low (< 18°C / 1800 mC), switch to Heat mode
action(thermostat, ThermostatDeviceType.self) {
SimplifiedThermostatTrait.setSystemMode(systemMode: .heat)
}
}.orElse {
// Otherwise, turn on the fan
action(fan, FanDeviceType.self) {
OnOffTrait.on()
}
}
}
Luồng có điều kiện lồng nhau
Bạn có thể lồng các khối có điều kiện vào bên trong các khối ifThen, elseIf hoặc orElse khác, cũng như kết hợp với các nút parallel, delay(for:) và stateReader.
Các khối ifThen, elseIf và orElse thực thi nội dung của chúng dưới dạng luồng tuần tự. Bạn có thể đặt bất kỳ nút tuần tự nào bên trong mỗi nhánh, bao gồm cả các khối action, stateReader, parallel, delay(for:) và ifThen lồng nhau.
Chậm trễ
Bạn có thể tạm dừng quy trình tự động hoá bằng phương thức delay(for:). Phương thức này nhận đối số Duration thể hiện thời gian tạm dừng trước khi tiếp tục thực thi. Thời lượng tạm dừng có thể ngắn nhất là 5 giây hoặc dài nhất là 24 giờ.
Ví dụ: để bật/tắt đèn 4 lần, mỗi lần cách nhau 5 giây:
typealias OnOffLightDevice = Matter.OnOffLightDeviceType
typealias OnOffTrait = Matter.OnOffTrait
sequential {
action(light, OnOffLightDevice.self) { OnOffTrait.toggle() }
delay(for:.seconds(5))
action(light, OnOffLightDevice.self) { OnOffTrait.toggle() }
delay(for:.seconds(5))
action(light, OnOffLightDevice.self) { OnOffTrait.toggle() }
delay(for:.seconds(5))
action(light, OnOffLightDevice.self) { OnOffTrait.toggle() }
}
Ngăn chặn điều kiện kích hoạt
Tính năng chặn điều kiện kích hoạt cho phép quy trình tự động hoá bỏ qua một starter trong một khoảng thời gian nhất định sau sự kiện kích hoạt ban đầu. Ví dụ: nếu quy trình tự động hoá có một starter được kích hoạt bằng tính năng phát hiện chuyển động và nếu bạn chỉ định thời gian chặn trình kích hoạt là 5 phút, thì khi starter kích hoạt, quy trình này sẽ không kích hoạt lại trong 5 phút tiếp theo. Việc này giúp ngăn quy trình tự động hoá kích hoạt liên tục.
Để áp dụng tính năng chặn điều kiện kích hoạt cho quy trình tự động hoá, hãy sử dụng từ khoá suppress(for:) cùng với đối số Duration thể hiện thời gian chờ trước khi phản hồi các điều kiện kích hoạt tiếp theo.
Thời gian chặn có thể ngắn nhất là 5 giây hoặc dài nhất là 24 giờ.
typealias OccupancySensorDevice = Matter.OccupancySensorDeviceType
typealias OnOffLightDevice = Matter.OnOffLightDeviceType
typealias MotionDetectionTrait = Google.MotionDetectionTrait
typealias OnOffTrait = Matter.OnOffTrait
automation {
let starterNode = starter(device, OccupancySensorDevice.self, MotionDetectionTrait.self)
starterNode
suppress(for: .seconds(30 * 60)) // 30 minutes
action(light, OnOffLightDevice.self) { OnOffTrait.toggle() }
}
Xin lưu ý rằng việc chặn điều kiện kích hoạt sẽ ảnh hưởng đến tất cả starters trong một quy trình tự động hoá trước Suppression.
Giới hạn số lần thực thi
Bạn có thể giới hạn số lần một quy trình tự động hoá được phép chạy.
Ví dụ: bạn có thể muốn thiết lập một quy trình tự động hoá một lần để chạy máy hút bụi khi bạn vắng nhà trong ngày.
Để thực hiện việc này, hãy đặt trường siêu dữ liệu maxExecutionCount của quy trình tự động hoá.
Ví dụ sau đây là một quy trình tự động hoá chỉ có thể thực thi một lần:
import GoogleHomeSDK
import GoogleHomeTypes
typealias RoboticVacuumCleanerDevice = Matter.RoboticVacuumCleanerDeviceType
typealias RvcRunModeTrait = Matter.RvcRunModeTrait
typealias AreaPresenceStateTrait = Google.AreaPresenceStateTrait
let draftAutomation = automation(
name: "Vacuum home away",
description: "Run the vacuum once when everyone is away.",
maxExecutionCount: 1
) {
let homeAwayState = starter(structure, AreaPresenceStateTrait.self)
homeAwayState
condition {
homeAwayState.presenceState.equals(.presenceStateVacant)
}
action(vacuum, RoboticVacuumCleanerDevice.self) {
RvcRunModeTrait.changeToMode(newMode: 1)
}
}
Quy trình tự động hoá sẽ bị xoá ngay sau khi hoàn tất lần thực thi cuối cùng và đạt đến maxExecutionCount. Mục nhật ký của quy trình tự động hoá vẫn còn trong thẻ Google Home app (GHA) Hoạt động, bao gồm cả automation_id.
Đặt thuộc tính đặc điểm trong một hành động
Cách đặt giá trị của thuộc tính đặc điểm:
- Tạo một nút
updatetrong nútaction, bao gồm cả đặc điểm liên quan làm đối số cho nútupdate:action(deviceReference, deviceType) { update(trait) { } } - Trong nút
update, đối với mỗi thuộc tính cần sửa đổi, hãy sử dụng hàm biến đổi và truyền giá trị mới cho hàm đó. Cách đặt tên cho hàm biến đổi:- Viết hoa tên thuộc tính
- Thêm tiền tố là từ
set.
defaultMoveRate, bạn sẽ sử dụng hàm biến đổi có tên làsetDefaultMoveRate.
Xin lưu ý rằng một nút update có thể có nhiều hàm biến đổi. Sau đây là ví dụ về việc cập nhật hai thuộc tính:
typealias FanDeviceType = Matter.FanDeviceType
typealias FanControlTrait = Matter.FanControlTrait
action(fan, FanDeviceType.self) {
update(FanControlTrait.self) {
$0.setFanMode(.on)
}
}