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 so với 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 Android.
Tuần tự với nhiều hành động
Một thao tác tự động có thể làm nhiều việc. Ví dụ: thay vì một nút action duy nhất, bạn có thể có nhiều nút action chạy theo thứ tự tuần tự:
automation {
sequential {
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, các thao tác sẽ thực thi đồng thời.
automation {
sequential {
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 này sẽ đợi thực thi cho đến khi tất cả các nút trong nút parallel hoàn tất quá trình thực thi.
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 thao tác hoặc đường dẫn khác nhau dựa trên các điều kiện thời gian chạy), hãy sử dụng câu lệnh if-then-else. Các câu lệnh này đượ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.
Trong khi một nút condition tiêu chuẩn sẽ chặn toàn bộ quy trình tự động hoá (nếu điều kiện đánh giá thành false, quy trình tự động hoá sẽ kết thúc ngay lập tức), thì các khối ifThen sẽ cho phép phân nhánh luồng điều khiển:
- Nút
condition: 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, 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 đáp ứng điều kiện nào.
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 thao tác hoặc nút DSL được lồng bên trong khối sẽ được thực thi. Nếu giá trị là false, 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 thao tác 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.
automation {
sequential {
val contactState = starter<_>(
contactSensor,
ContactSensorDevice,
BooleanState,
)
val lightState = stateReader<_>(
light,
DimmableLightDevice,
OnOff,
)
condition {
// Door opened (contact sensor open)
expression = contactState.stateValue equals false
}
// Conditionally turn on the light if it's off
ifThen(lightState.onOff equals false) {
action(light, DimmableLightDevice) { command(OnOff.on()) }
}
// Continue executing subsequent actions in the sequential flow
action(structure) {
command(AssistantBroadcast.broadcast("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 nhóm hành động khi một điều kiện là đúng và một nhóm hành động thay thế khi điều kiện đó là sai, hãy xâu chuỗi 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.
automation {
sequential {
val doorLockEvent = starter<_>(
doorLock,
DoorLockDevice,
LockOperationEvent,
)
val lightState = stateReader<_>(
light,
DimmableLightDevice,
OnOff,
)
condition {
expression =
doorLockEvent.lockOperationType equals LockOperationTypeEnum.Unlock
}
ifThen(lightState.onOff equals false) {
action(light, DimmableLightDevice) { command(OnOff.on()) }
}.orElse {
action(structure) {
command(AssistantBroadcast.broadcast("Welcome home!"))
}
}
}
}
Liên kết nhiều điều kiện theo trình tự
Bạn có thể xâu chuỗi 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 đánh giá thành true, 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.
automation {
sequential {
val tempStarter = starter<_>(
tempSensor,
TemperatureSensorDevice,
TemperatureMeasurement,
)
// If temperature is high (>= 28°C / 2800 mC), switch thermostat to Cool mode
ifThen(tempStarter.measuredValue greaterThanOrEquals 2800) {
action(thermostat, ThermostatDevice) {
command(
SimplifiedThermostat.setSystemMode(
SimplifiedThermostatSystemModeEnum.Cool
)
)
}
}.elseIf(tempStarter.measuredValue lessThan 1800) {
// If temperature is low (< 18°C / 1800 mC), switch to Heat mode
action(thermostat, ThermostatDevice) {
command(
SimplifiedThermostat.setSystemMode(
SimplifiedThermostatSystemModeEnum.Heat
)
)
}
}.orElse {
// Otherwise, turn on the fan
action(fan, FanDevice) {
command(OnOff.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 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, delayFor và stateReader.
Các khối ifThen, elseIf và orElse thực thi nội dung của chúng dưới dạng các luồng tuần tự. Bạn có thể đặt mọi nút tuần tự bên trong mỗi nhánh, bao gồm cả action, stateReader, parallel, delayFor và các khối ifThen lồng nhau.
Chậm trễ
Bạn có thể tạm dừng quy trình tự động hoá bằng cách sử dụng từ khoá delayFor. Từ khoá này nhận một đối số java.time.Duration biểu thị khoảng thời gian tạm dừng trước khi tiếp tục thực thi. Thời gian 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:
sequential {
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
delayFor(Duration.ofSeconds(5))
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
delayFor(Duration.ofSeconds(5))
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
delayFor(Duration.ofSeconds(5))
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
}
Chặn điều kiện kích hoạt
Tính năng ngăn chặn kích hoạt cho phép quy trình tự động hoá của bạn bỏ qua một starter trong một khoảng thời gian cụ thể sau sự kiện kích hoạt ban đầu. Ví dụ: nếu chế độ tự động hoá có 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 lượng chặn kích hoạt là 5 phút, thì khi starter kích hoạt, chế độ này sẽ không kích hoạt lại trong 5 phút tiếp theo. Điều này ngăn quy trình tự động hoá kích hoạt nhanh nhiều lần.
Để áp dụng tính năng chặn kích hoạt cho quy trình tự động hoá, hãy sử dụng từ khoá suppressFor với đối số java.time.Duration biểu thị khoảng thời gian chờ trước khi phản hồi các sự 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ờ.
automation {
sequential {
val starterNode = starter<_>(device, OccupancySensor, MotionDetection)
suppressFor(Duration.ofMinutes(30))
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
}
Xin lưu ý rằng tính năng chặn kích hoạt sẽ ảnh hưởng đến tất cả starters trong một quy trình tự động hoá diễn ra trước suppressFor.
Giới hạn số lần thực thi
Bạn có thể giới hạn số lần được phép chạy một quy trình tự động hoá.
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à cả ngày.
Để làm như vậ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:
automation { // The automation can only be executed once. maxExecutionCount = 1 // When the door lock state changes sequential { val doorLockEvent = starter<_>(doorLock, DoorLockDevice, LockOperationEvent) // if the door is unlocked condition() { expression = (doorLockEvent.lockOperationType equals LockOperationTypeEnum.Unlock) } // turn the light on action(light, DimmableLightDevice) { command(OnOff.on()) } } }
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ập 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ị cho một 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 dùng một hàm đột biến và truyền giá trị mới cho hàm đó. Cách tạo tên của hàm biến đổi:- Viết hoa tên thuộc tính
- Thêm từ
setvào trước tên hàm.
defaultMoveRate, bạn sẽ dùng một hàm sửa đổi có tên làsetDefaultMoveRate.
Xin lưu ý rằng một nút update có thể có nhiều hàm đột biến. Sau đây là ví dụ về trường hợp cập nhật 2 thuộc tính:
action(device, Fan) {
update(FanControl) {
setPercentSetting(50u)
setRockSetting(FanControlCluster.RockBitmap.rockUpDown)
}
}