DSL Otomatisasi dapat digunakan untuk membuat otomatisasi yang lebih kompleks daripada yang dibahas dalam Panduan DSL - otomatisasi dasar di iOS.
Berurutan dengan beberapa tindakan
Otomatisasi dapat melakukan lebih dari satu hal. Misalnya, sebagai pengganti satu node action, Anda dapat memiliki beberapa node action, yang berjalan secara berurutan:
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
starter(...)
condition {...}
action {...}
action {...}
action {...}
}
Berurutan dengan beberapa tindakan paralel
Jika Anda menempatkan beberapa node action dalam node parallel, tindakan akan dijalankan
secara serentak.
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
starter(...)
condition {...}
parallel {
action {...}
action {...}
action {...}
}
}
Jika ada node action di node sequential yang muncul setelah node parallel, node tersebut akan menunggu untuk dieksekusi hingga semua node dalam node parallel selesai dieksekusi.
Eksekusi bersyarat
Secara default, otomatisasi menjalankan node secara berurutan atau paralel. Jika Anda
memerlukan logika percabangan bersyarat—menjalankan tindakan atau jalur yang berbeda berdasarkan
kondisi runtime—gunakan pernyataan if-then-else, yang dibuat menggunakan
blok DSL alur kontrol bersyarat:
ifThen,
elseIf,
dan
orElse.
Meskipun node condition standar membatasi seluruh otomatisasi (jika kondisi
dievaluasi ke false, otomatisasi akan segera menghentikan eksekusi), blok ifThen
memungkinkan alur kontrol percabangan:
- Node
condition: Menghentikan eksekusi seluruh otomatisasi (atau jalur eksekusi saat ini) jika ekspresinya adalahfalse. ifThen/elseIf/orElse: Mengevaluasi kondisi secara berurutan. Jika suatu kondisi bernilaifalse, eksekusi akan beralih ke cabangelseIfberikutnya, cabang penggantianorElse, atau berlanjut ke node berikutnya dalam otomatisasi jika tidak ada kondisi yang terpenuhi.
Menjalankan tindakan berdasarkan kondisi
Blok ifThen mengevaluasi ekspresi kondisional. Jika ekspresi
dievaluasi ke true, tindakan atau node DSL yang bertingkat di dalam blok akan
dieksekusi. Jika bernilai false, tindakan akan dilewati, dan
otomatisasi akan berlanjut ke node berikutnya dalam alur berurutan.
Anda dapat menggunakan blok ifThen mandiri jika hanya ingin melakukan tindakan
secara bersyarat tanpa memblokir atau menghentikan node berikutnya dalam
otomatisasi:
// 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.")
}
}
Menjalankan tindakan yang berbeda berdasarkan kondisi
Untuk menjalankan satu set tindakan saat kondisi bernilai benar dan set tindakan alternatif saat kondisi bernilai salah, buat rantai blok .orElse { ... } opsional setelah 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!")
}
}
}
Menghubungkan beberapa kondisi secara berurutan
Anda dapat merangkai satu atau beberapa blok .elseIf(...) { ... } opsional untuk mengevaluasi beberapa kondisi secara berurutan. Cabang pertama yang kondisinya bernilai true akan dieksekusi, dan semua cabang yang tersisa akan dilewati. Jika tidak ada kondisi yang bernilai true, blok .orElse { ... } opsional akan dieksekusi (jika disediakan):
// 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()
}
}
}
Alur bersyarat bertingkat
Blok kondisional dapat disusun bertingkat di dalam blok ifThen, elseIf, atau orElse
lainnya, serta digabungkan dengan node parallel, delay(for:),
dan stateReader.
Blok ifThen, elseIf, dan orElse mengeksekusi kontennya sebagai alur berurutan. Anda dapat menempatkan node berurutan apa pun di dalam setiap cabang, termasuk
action, stateReader, parallel, delay(for:), dan blok ifThen bertingkat.
Keterlambatan
Anda dapat menjeda otomatisasi menggunakan metode
delay(for:),
yang menggunakan argumen
Duration
yang mewakili durasi jeda sebelum melanjutkan eksekusi. Durasi jeda
dapat sesingkat lima detik atau selama 24 jam.
Misalnya, untuk mengaktifkan lampu empat kali dengan jeda lima detik di antara setiap pengaktifan:
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() }
}
Pencegatan pemicu
Penekanan pemicu adalah kemampuan yang memungkinkan otomatisasi Anda mengabaikan
starter selama jangka waktu tertentu setelah peristiwa pemicu awal. Misalnya, jika otomatisasi memiliki starter yang dipicu oleh deteksi gerakan,
dan jika Anda menentukan durasi penekanan pemicu selama lima menit, maka saat
starter dipicu, pemicu tidak akan dipicu lagi selama lima menit berikutnya. Hal ini
mencegah otomatisasi dipicu berulang kali dengan cepat.
Untuk menerapkan penekanan pemicu ke otomatisasi Anda, gunakan kata kunci
suppress(for:)
dengan argumen
Duration
yang mewakili durasi waktu tunggu sebelum merespons pemicu berikutnya.
Durasi penonaktifan dapat sesingkat lima detik atau selama 24 jam.
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() }
}
Perhatikan bahwa penekanan pemicu memengaruhi semua starters dalam otomatisasi yang
mendahului Suppression.
Membatasi jumlah eksekusi
Anda dapat membatasi frekuensi otomatisasi diizinkan untuk berjalan.
Misalnya, Anda mungkin ingin menyiapkan otomatisasi satu kali yang menjalankan penyedot debu saat Anda pergi dari rumah selama sehari.
Untuk melakukannya, tetapkan kolom metadata maxExecutionCount otomatisasi.
Contoh berikut adalah otomatisasi yang hanya dapat dijalankan sekali:
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)
}
}
Otomatisasi akan segera dihapus setelah selesai dieksekusi untuk terakhir kalinya dan maxExecutionCount tercapai. Entri histori otomatisasi tetap ada
di tab Google Home app (GHA) Aktivitas, termasuk automation_id.
Menetapkan atribut ciri dalam tindakan
Untuk menetapkan nilai atribut karakteristik:
- Buat node
updatedalam nodeaction, termasuk karakteristik yang relevan sebagai argumen untuk nodeupdate:action(deviceReference, deviceType) { update(trait) { } } - Dalam node
update, untuk setiap atribut yang akan diubah, gunakan fungsi mutator, dan teruskan nilai baru ke fungsi tersebut. Untuk membentuk nama fungsi mutator:- Gunakan huruf kapital untuk nama atribut
- Awali dengan kata
set.
defaultMoveRate, Anda akan menggunakan fungsi mutator bernamasetDefaultMoveRate.
Perhatikan bahwa node update dapat memiliki beberapa fungsi mutator. Berikut
contoh dua atribut yang diperbarui:
typealias FanDeviceType = Matter.FanDeviceType
typealias FanControlTrait = Matter.FanControlTrait
action(fan, FanDeviceType.self) {
update(FanControlTrait.self) {
$0.setFanMode(.on)
}
}