Konsep DSL Android

Berikut adalah ringkasan konsep dasar DSL Automation di Android.

Komponen otomatisasi

Otomatisasi terdiri dari komponen dasar berikut, yang biasanya dievaluasi dalam urutan ini:

  1. Pemicu — Menentukan kondisi awal yang mengaktifkan otomatisasi, seperti perubahan pada karakteristik. Otomatisasi harus memiliki pemicu.
  2. Kondisi — Batasan tambahan apa pun yang akan dievaluasi setelah otomatisasi diaktifkan. Ekspresi dalam Kondisi harus bernilai true agar tindakan otomatisasi dapat dilanjutkan.
  3. Tindakan — Perintah atau pembaruan status yang dilakukan saat semua kondisi telah terpenuhi.

Misalnya, Anda mungkin memiliki otomatisasi yang meredupkan lampu di ruangan saat TV di ruangan tersebut dinyalakan antara matahari terbenam dan matahari terbit. Dalam contoh ini:

  1. Pemicu — TV diaktifkan, yang merupakan perubahan status pada ciri TV.
  2. Kondisi— Waktu saat ini untuk rumah tempat TV berada akan dievaluasi.
  3. Tindakan — Lampu di ruangan yang sama dengan TV diredupkan.

Otomatisasi akan diaktifkan saat TV di ruangan dinyalakan, tetapi otomatisasi hanya akan dijalankan jika kondisi "waktu antara matahari terbenam dan matahari terbit" terpenuhi.

Selain struktur dasar, otomatisasi di Home API juga berisi metadata, seperti nama dan deskripsi, yang dapat digunakan untuk mengidentifikasinya bagi developer dan pengguna.

Node

Di Home API, struktur logis otomatisasi terdiri dari node. Node adalah unit abstrak yang dapat digunakan kembali, yang mewakili perilaku entity atau alur eksekusi. Setiap node dapat memiliki variabel input, serta variabel output yang dapat digunakan oleh node lain.

Tabel: Jenis node otomatisasi
Node Jenis Nodus Implementasi Kotlin Deskripsi
Starter Perilaku StarterNodeDsl Memulai otomatisasi saat status karakteristik (atribut apa pun) berubah.
StateReader Perilaku StateReaderNodeDsl Membaca atribut karakteristik dan memungkinkan Anda mengambil nilainya untuk digunakan dalam node kondisi.
Tindakan Perilaku ActionNodeDsl Memanggil perintah karakteristik.
Berurutan Alur eksekusi SequentialFlow Menjalankan node tindakan bertingkat secara berurutan. Ini adalah perilaku eksekusi default.
Paralel Alur eksekusi ParallelFlow Menjalankan node tindakan bertingkat secara paralel.
Kondisi Alur eksekusi ConditionNodeDsl Mengubah alur eksekusi secara bersyarat berdasarkan evaluasi ekspresi logis. Kondisi dapat dikaitkan dengan pemicu (kondisi khusus pemicu) atau bersifat global (berlaku untuk semua pemicu).
Pilih Alur eksekusi SelectFlow Memungkinkan lebih dari satu pemicu untuk mengaktifkan otomatisasi.
IfFlow Alur eksekusi IfFlowDsl Menjalankan maksimal satu tindakan (atau cabang) berdasarkan kondisi (jika ada) yang bernilai benar (mirip dengan pernyataan if-then-else).
Ekspresi Nilai Expression Dapat berupa nilai atribut karakteristik, konstanta, atau nilai literal, dan harus dievaluasi ke daftar, angka, boolean, atau string.

Node perilaku

Node seperti pemicu dan tindakan adalah node perilaku. Pemicu mengaktifkan otomatisasi berdasarkan perubahan atribut perangkat. Tindakan mengeluarkan perintah perangkat atau memperbarui atribut.

Node perilaku biasanya terkait dengan karakteristik perangkat dan status karakteristik output untuk digunakan sebagai input di node lain.

Node alur eksekusi

Beberapa node merepresentasikan alur eksekusi, seperti berurutan dan paralel. Setiap node ini berisi node perilaku yang menentukan otomatisasi.

Misalnya, alur berurutan dapat berisi node yang dieksekusi secara berurutan. Biasanya, ini adalah pemicu, kondisi, dan tindakan.

Alur eksekusi berurutan
Gambar 1: Alur otomatisasi berurutan

Flow paralel dapat memiliki beberapa node tindakan yang dieksekusi secara bersamaan, seperti menyalakan beberapa lampu secara bersamaan. Node yang mengikuti alur paralel tidak akan dieksekusi hingga semua cabang alur paralel selesai.

Alur eksekusi paralel
Gambar 2: Alur otomatisasi paralel

Jenis alur eksekusi lainnya adalah alur kondisi, yang dapat mengubah alur eksekusi berdasarkan evaluasi ekspresi.

Misalnya, Anda mungkin memiliki otomatisasi yang melakukan tindakan berdasarkan apakah waktu saat ini adalah malam hari. Node kondisi memeriksa waktu, lalu mengikuti jalur eksekusi yang sesuai berdasarkan evaluasi tersebut.

Alur kondisi
Gambar 3: Alur kondisi

Alur pilihan berguna jika Anda ingin memiliki lebih dari satu pemicu yang dapat mengaktifkan otomatisasi Anda. Jika Anda menyertakan dua pemicu atau lebih dalam alur select, salah satu pemicu dapat mengaktifkan otomatisasi.

Misalnya, Anda dapat menulis otomatisasi yang menurunkan tirai saat matahari terbenam, jika suhu naik di atas batas tertentu, atau jika kecerahan melebihi batas. Tiga pemicu terpisah menangani setiap skenario ini, dan ketiganya akan digabungkan dalam alur select.

Pilih alur
Gambar 4: Pilih alur

Alur if-then-else (IfFlow) memungkinkan eksekusi kondisional percabangan dalam otomatisasi. Tidak seperti node condition, yang menghentikan seluruh otomatisasi jika kondisinya false, alur if-then-else secara bersyarat mengeksekusi tindakan tertentu saat kondisi terpenuhi, dan dapat beralih ke kondisi alternatif atau tindakan penggantian, atau melanjutkan ke node berikutnya dalam otomatisasi. Untuk mengetahui detail selengkapnya, lihat Eksekusi bersyarat.

Alur bertingkat

Dalam otomatisasi yang kompleks, node alur eksekusi juga dapat disusun bertingkat. Misalnya, Anda mungkin memiliki alur berurutan yang menjalankan alur paralel.

Alur eksekusi bertingkat
Gambar 5: Alur eksekusi bertingkat

Node DSL dapat disusun bertingkat dan digabungkan dengan berbagai cara untuk memenuhi kebutuhan spesifik Anda, sesuai dengan batasan yang diuraikan dalam tabel berikut. Kolom Builder menautkan ke dokumentasi builder typesafe Kotlin, yang menjelaskan secara mendetail apa yang diizinkan untuk digunakan di setiap jenis node.

Tabel: Cara node dapat digabungkan
Node Dapat berisi jenis node dan data berikut Harus berada dalam salah satu jenis node berikut
Starter Ekspresi Pilih, Berurutan
ManualStarter Pilih, Berurutan
StateReader Ekspresi (biasanya terdiri dari nilai atribut karakteristik) IfFlow, Parallel, Sequential
Tindakan Perintah, Entitas, Ekspresi IfFlow, Parallel, Select, Sequential
Berurutan IfFlow, Parallel, Select, Sequential
Paralel Tindakan IfFlow, Sequential
Kondisi Ekspresi IfFlow, Parallel, Sequential
Pilih Condition, Sequential, Starter, ManualStarter Berurutan, dan harus menjadi node pertama dalam alur
IfFlow Action, Condition, Delay, IfFlow, Parallel, Sequential, StateReader, Suppression Berurutan

DSL Otomatisasi

Di Home API, otomatisasi ditentukan menggunakan DSL (Domain-Specific Language) Otomatisasi. DSL Automation diimplementasikan sebagai DSL Kotlin (bahasa khusus domain), menggunakan builder jenis aman Kotlin dan dirancang khusus untuk menentukan template otomatisasi.

Saat otomatisasi dikompilasi, builder yang aman untuk jenis Kotlin akan menghasilkan class data Kotlin yang kemudian diserialisasi ke JSON buffering protokol, yang digunakan untuk melakukan panggilan ke Layanan Otomatisasi Google.

DSL Otomatisasi menyederhanakan dan mengefisienkan proses pembuatan otomatisasi. Secara native, API ini menggunakan model data yang sama dengan karakteristik standar Matter dan karakteristik smart home yang ditampilkan di Device API.

DSL Otomatisasi juga menentukan logika otomatisasi dalam hal jenis perangkat abstrak, bukan instance perangkat tertentu yang terletak di rumah pengguna. Hal ini memungkinkan developer memberikan parameter input yang dapat digunakan saat runtime untuk menentukan instance perangkat yang sebenarnya, serta parameter value penting lainnya.

Sintaksis DSL mirip dengan Kotlin, dan sama-sama aman dari segi jenis, tetapi otomatisasi yang ditulis dalam DSL Otomatisasi lebih sederhana dan lebih ringkas daripada otomatisasi yang sama yang ditulis dalam Kotlin murni.

Contoh

Berikut adalah contoh otomatisasi yang mengaktifkan perangkat, yang ditulis menggunakan DSL Otomatisasi:

val automation = automation {
  name = "MyFirstAutomation"
  description = "If light1 is on, turn on light2."
  isActive = true
  sequential {
    val onOffTrait = starter<_>(device1, OnOffLightDevice, OnOff)
    condition() { expression = onOffTrait.onOff equals true }
    action(device2, OnOffLightDevice) { command(OnOff.on()) }
  }
}

Otomatisasi ini sangat dasar: saat device1, lampu, menyala (atribut onOff berubah menjadi true), lalu mengirim perintah on() untuk menyalakan device2.

Otomatisasi menggunakan node sequential, yang menunjukkan bahwa nodenya akan berjalan secara berurutan.

Dalam node sequential terdapat node perilaku seperti starter, condition, dan action. Output node starter ditetapkan ke variabel untuk digunakan di node condition.