Panduan DSL iOS

Gunakan panduan berikut untuk memahami cara berbagai node Automation DSL dapat digunakan untuk membuat otomatisasi.

Semua Automation DSL ditempatkan dalam satu node automation. Node automation membentuk batas antara konteks bahasa Swift luar dan konteks DSL yang disematkan.

Alur berurutan

Alur berurutan adalah jenis alur otomatisasi default.

Contoh DSL berurutan

Berikut adalah template Automation DSL yang sangat dasar yang menggunakan alur berurutan yang terdiri dari pemicu, kondisi, dan tindakan:

import GoogleHomeSDK
import GoogleHomeTypes

automation (
...
) {
  starter(...)
  condition {...}
  action {...}
}

Hal ini dapat disempurnakan dengan menambahkan node tambahan.

Pemicu

Node pemicu menentukan keadaan awal yang mengaktifkan otomatisasi. Misalnya, perubahan status atau nilai. Otomatisasi harus memiliki setidaknya satu pemicu, jika tidak, validasi akan gagal. Untuk menambahkan lebih dari satu pemicu ke otomatisasi, Anda harus menggunakan node select.

Pemicu berdasarkan atribut fitur

Saat mendeklarasikan node pemicu yang didasarkan pada atribut fitur, tentukan:

  • perangkat
  • jenis perangkat yang memiliki fitur
  • fitur
starter(
  thermostat,
  Matter.TemperatureSensorDeviceType.self,
  Matter.TemperatureMeasurementTrait.self
)

Parameter jenis perangkat diperlukan karena parameter ini memungkinkan Anda menentukan jenis perangkat dalam perangkat yang ditangani oleh otomatisasi. Misalnya, perangkat mungkin terdiri dari FanDeviceType dan HeatingCoolingUnitDeviceType, yang keduanya berisi OnOffTrait fitur. Dengan menentukan jenis perangkat, tidak ada ambiguitas tentang bagian perangkat mana yang memicu otomatisasi.

Pemicu berdasarkan peristiwa

Saat mendeklarasikan node pemicu yang didasarkan pada peristiwa, tentukan:

  • perangkat
  • jenis perangkat yang memiliki fitur
  • peristiwa
starter(
  doorbell,
  Google.GoogleDoorbellDeviceType.self,
  Google.DoorbellPressTrait.DoorbellPressedEvent
)

Pemicu berdasarkan struktur dan peristiwa, dengan parameter

Beberapa peristiwa dapat memiliki parameter, sehingga parameter ini juga harus disertakan dalam pemicu.

Misalnya, pemicu ini menggunakan TimeTrait's ScheduledEvent untuk mengaktifkan otomatisasi pada pukul 07.00:

typealias TimeTrait = Google.TimeTrait

let earlyMorning = starter(
  structure,
  TimeTrait.ScheduledEvent.self
) {
  TimeTrait.ScheduledEvent.clockTime(TimeOfDay(hours: 7, minutes: 0))
}

Pemicu berdasarkan cuaca

Anda dapat menentukan kondisi cuaca saat ini atau yang diperkirakan dalam pemicu, menggunakan fitur Cuaca:

let weatherState = starter<_>(structure, trait = Weather)

Lihat Tutup tirai jika kemungkinan akan hujan di halaman Contoh otomatisasi.

Pemicu manual

Pemicu manual adalah jenis pemicu khusus yang memungkinkan pengguna menjalankan otomatisasi secara manual.

Saat mendeklarasikan pemicu manual:

  • Jangan tentukan jenis fitur atau perangkat.
  • Sediakan elemen UI yang memanggil Automation.execute().

Saat menempatkan pemicu manual dalam alur select bersama dengan pemicu lain, pemicu manual akan mengganti pemicu lainnya:

select {
  manualStarter()
  starter(
    thermostat,
    Matter.TemperatureSensorDeviceType.self,
    Matter.TemperatureMeasurementTrait.self
  )
}

Perhatikan bahwa node condition apa pun yang mengikuti pemicu manual akan dievaluasi, dan dapat memblokir eksekusi otomatisasi, bergantung pada ekspresi condition.

Memisahkan pemicu manual dari pemicu bersyarat

Salah satu cara untuk menyusun otomatisasi agar node condition tidak memblokir otomatisasi yang diaktifkan dengan pemicu manual adalah dengan menempatkan pemicu lain dalam alur berurutan terpisah bersama dengan condition-nya:

import GoogleHomeSDK
import GoogleHomeTypes

automation (
...
) {

  select {
    sequential {
      starter(...)
      condition {...}
    }
    sequential {
      manualStarter()
    }
  }
  action {...}

}

Mereferensikan nilai atribut

Untuk menggunakan nilai atribut dalam ekspresi, gunakan sintaksis berikut.

Dengan stateReader:

typealias TimeTrait = Google.TimeTrait

let time = stateReader(structure, TimeTrait.self)
time
let currTime = time.currentTime

Dengan starter:

typealias LaundryWasherDeviceType = Matter.LaundryWasherDeviceType
typealias OnOffTrait = Google.OnOffTrait

let starterNode = starter(device1, LaundryWasherDeviceType.self, OnOffTrait.self)
starterNode
condition {
  starterNode.onOff.equals(true)
}

Node dan ekspresi kondisi

Node kondisi mewakili titik keputusan yang menentukan apakah otomatisasi akan dilanjutkan atau tidak. Otomatisasi dapat memiliki beberapa node condition. Jika ekspresi node condition dievaluasi ke false, eksekusi seluruh otomatisasi akan berakhir.

Dalam node condition, Anda dapat menggabungkan beberapa kriteria kondisi menggunakan berbagai operator, selama ekspresi dievaluasi ke satu nilai boolean. Jika nilai yang dihasilkan adalah true, kondisi akan terpenuhi dan otomatisasi akan melanjutkan eksekusi node berikutnya. Jika false, otomatisasi akan berhenti dieksekusi pada saat itu.

Ekspresi dibentuk mirip dengan ekspresi di Swift, dan dapat berisi nilai primitif seperti angka, karakter, string, dan boolean, serta nilai Enum. Mengelompokkan sub-ekspresi dengan tanda kurung memungkinkan Anda mengontrol urutan evaluasinya.

Berikut adalah contoh condition yang menggabungkan beberapa sub-ekspresi menjadi satu ekspresi:

condition {
  let exp1 = starterNode.lockState.equals(.unlocked)
  let exp2 = stateReaderNode.lockState.equals(true)
  let exp3 = occupancySensingDevice.occupied.notEquals(0)
  (exp1.and(exp2)).or(exp3)
}

Anda dapat mereferensikan nilai fitur yang diakses melalui pemicu:

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

Cara lain untuk mereferensikan nilai atribut fitur dalam node condition adalah dengan node stateReader.

Untuk melakukannya, pertama-tama ambil nilai atribut fitur dalam node stateReader. stateReader menggunakan structure dan fitur sebagai argumen:

typealias ActivatedCarbonFilterMonitoringTrait = Matter.ActivatedCarbonFilterMonitoringTrait

let filterMonitoringState = stateReader(structure, ActivatedCarbonFilterMonitoringTrait.self)

Kemudian, referensikan stateReader di node condition:

condition {
filterMonitoringState.changeIndication.equals(.warning)
}

Dengan menggunakan operator perbandingan dan logika, beberapa stateReaders dapat digunakan dalam node 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)
}

Durasi kondisi

Selain ekspresi boolean dalam kondisi, Anda dapat menentukan jangka waktu selama ekspresi harus benar agar otomatisasi dapat dijalankan. Misalnya, Anda dapat menentukan kondisi yang hanya diaktifkan jika lampu telah menyala selama sepuluh menit.

condition(for: .seconds(600)) {
lightStateReader.onOff.equals(true)
}

Durasi dapat berkisar antara satu hingga 30 menit.

Node tindakan

Node tindakan adalah tempat otomatisasi bekerja. Dalam contoh ini, tindakan memanggil perintah AssistantBroadcastTrait's broadcast():

action(speaker, SpeakerDeviceType.self) {
  Google.AssistantBroadcastTrait.broadcast(msg: "Oven Cycle Complete")
}