Memeriksa apakah suatu trait mendukung perintah
Dukungan juga dapat diperiksa untuk perintah trait. Gunakan juga fungsi supports
tingkat karakteristik untuk memeriksa apakah perintah didukung untuk perangkat tertentu.
Misalnya, untuk memeriksa dukungan perangkat terhadap perintah
toggle
fitur On/Off:
// Check if the OnOff trait supports the toggle command. if (onOffTrait.supports(OnOff.Command.Toggle)) { println("onOffTrait supports toggle command") } else { println("onOffTrait does not support stateful toggle command") }
Mengirim perintah ke perangkat
Mengirim perintah mirip dengan membaca atribut status dari trait. Untuk
mengaktifkan atau menonaktifkan perangkat, gunakan
perintah Toggle dari
OnOff
trait, yang ditentukan dalam model data ekosistem Google Home sebagai toggle()
. Metode ini mengubah onOff
menjadi false
jika onOff
adalah true
, atau
menjadi true
jika onOff
adalah false
:
// Calling a command on a trait. try { onOffTrait.toggle() } catch (e: HomeException) { // Code for handling the exception }
Semua perintah trait adalah fungsi suspend
dan hanya selesai saat respons
dikembalikan oleh API (seperti mengonfirmasi bahwa status perangkat telah berubah).
Perintah dapat menampilkan pengecualian jika masalah terdeteksi pada alur eksekusi. Sebagai developer, Anda harus menggunakan blok try-catch
untuk menangani pengecualian ini dengan benar dan menampilkan informasi mendetail kepada pengguna dalam kasus ketika error dapat ditindaklanjuti. Pengecualian yang tidak ditangani akan menghentikan runtime aplikasi dan dapat menyebabkan error di aplikasi Anda.
Atau, gunakan perintah off()
atau on()
untuk menetapkan status secara eksplisit:
onOffTrait.off() onOffTrait.on()
Setelah mengirim perintah untuk mengubah status, setelah selesai, Anda dapat membaca status seperti yang dijelaskan dalam Membaca status perangkat untuk menanganinya di aplikasi Anda. Atau, gunakan alur seperti yang dijelaskan dalam Mengamati status, yang merupakan metode yang lebih disukai.
Mengirim perintah dengan parameter
Beberapa perintah dapat menggunakan parameter, seperti yang ada pada
OnOff
atau
LevelControl
trait:
offWithEffect
// Turn off the light using the DyingLight effect. onOffTrait.offWithEffect( effectIdentifier = OnOffTrait.EffectIdentifierEnum.DyingLight, effectVariant = 0u, )
moveToLevel
// Change the brightness of the light to 50% levelControlTrait.moveToLevel( level = 127u.toUByte(), transitionTime = null, optionsMask = LevelControlTrait.OptionsBitmap(), optionsOverride = LevelControlTrait.OptionsBitmap(), )
Beberapa perintah memiliki argumen opsional, yang muncul setelah argumen wajib.
Misalnya, perintah step
untuk trait FanControl
memiliki dua argumen opsional:
val fanControlTraitFlow: Flow<FanControl?> = device.type(FanDevice).map { it.standardTraits.fanControl }.distinctUntilChanged() val fanControl = fanControlTraitFlow.firstOrNull() // Calling a command with optional parameters not set. fanControl?.step(direction = FanControlTrait.StepDirectionEnum.Increase) // Calling a command with optional parameters. fanControl?.step(direction = FanControlTrait.StepDirectionEnum.Increase) { wrap = true }
Memeriksa apakah suatu karakteristik mendukung atribut
Beberapa perangkat mungkin mendukung trait Matter, tetapi tidak mendukung atribut tertentu. Misalnya, perangkat Cloud-to-cloud yang dipetakan ke Matter mungkin tidak mendukung setiap atribut Matter. Untuk menangani kasus seperti ini, gunakan fungsi supports
tingkat karakteristik dan enum Attribute
karakteristik untuk memeriksa apakah atribut didukung untuk perangkat tertentu.
Misalnya, untuk memeriksa dukungan perangkat terhadap atribut
onOff
fitur Aktif/Nonaktif:
// Check if the OnOff trait supports the onOff attribute. if (onOffTrait.supports(OnOff.Attribute.onOff)) { println("onOffTrait supports onOff state") } else { println("onOffTrait is for a command only device!") }
Beberapa atribut dapat bernilai null dalam spesifikasi Matter atau
skema Cloud-to-cloud smart home. Untuk atribut ini, Anda dapat menentukan apakah null yang ditampilkan oleh atribut disebabkan oleh perangkat yang tidak melaporkan nilai tersebut, atau apakah nilai atribut sebenarnya adalah null
, dengan menggunakan isNullable
selain supports
:
// Check if a nullable attribute is set or is not supported. if (onOffTrait.supports(OnOff.Attribute.startUpOnOff)) { // The device supports startupOnOff, it is safe to expect this value in the trait. if (OnOff.Attribute.startUpOnOff.isNullable && onOffTrait.startUpOnOff == null) { // This value is nullable and set to null. Check the specification as to // what null in this case means println("onOffTrait supports startUpOnOff and it is null") } else { // This value is nullable and set to a value. println("onOffTrait supports startUpOnOff and it is set to ${onOffTrait.startUpOnOff}") } } else { println("onOffTrait does not support startUpOnOff!") }
Memperbarui atribut karakteristik
Jika Anda ingin mengubah nilai atribut tertentu, dan tidak ada perintah trait yang melakukannya, atribut tersebut mungkin mendukung penetapan nilai secara eksplisit.
Apakah nilai atribut dapat diubah bergantung pada dua faktor:
- Apakah atribut dapat ditulis?
- Dapatkah nilai atribut berubah sebagai efek samping dari pengiriman perintah trait?
Dokumentasi referensi untuk ciri dan atributnya memberikan informasi ini.
Oleh karena itu, kombinasi properti yang menentukan cara nilai atribut dapat diubah adalah:
Hanya baca dan tidak terpengaruh oleh perintah lain. Artinya, nilai atribut tidak berubah. Misalnya, atribut
currentPosition
dari sifatSwitch
.Hanya baca dan terpengaruh oleh perintah lain. Artinya, satu-satunya cara nilai atribut dapat berubah adalah sebagai hasil pengiriman perintah. Misalnya, atribut
currentLevel
dari sifatLevelControl
Matter bersifat hanya baca, tetapi nilainya dapat diubah oleh perintah sepertimoveToLevel
.Dapat ditulis dan tidak terpengaruh oleh perintah lain. Artinya, Anda dapat mengubah nilai atribut secara langsung menggunakan fungsi
update
dari trait, tetapi tidak ada perintah yang akan memengaruhi nilai atribut. Misalnya, atributWrongCodeEntryLimit
dari sifatDoorLock
.Dapat ditulis dan terpengaruh oleh perintah lain. Artinya, Anda dapat mengubah nilai atribut secara langsung menggunakan fungsi
update
dari trait, dan nilai atribut dapat berubah sebagai hasil dari pengiriman perintah. Misalnya, atributspeedSetting
dariFanControlTrait
dapat ditulis secara langsung, tetapi juga dapat diubah menggunakan perintahstep
.
Contoh penggunaan fungsi update untuk mengubah nilai atribut
Contoh ini menunjukkan cara menetapkan nilai atribut
DoorLockTrait.WrongCodeEntryLimit
secara eksplisit.
Untuk menetapkan nilai atribut, panggil fungsi update
trait dan teruskan fungsi mutator yang menetapkan nilai baru.
Sebaiknya verifikasi terlebih dahulu bahwa trait mendukung atribut.
Contoh:
val doorLockDevice = home.devices().list().first { device -> device.has(DoorLock) } val traitFlow: Flow<DoorLock?> = doorLockDevice.type(DoorLockDevice).map { it.standardTraits.doorLock }.distinctUntilChanged() val doorLockTrait: DoorLock = traitFlow.first()!! if (doorLockTrait.supports(DoorLock.Attribute.wrongCodeEntryLimit)) { val unused = doorLockTrait.update { setWrongCodeEntryLimit(3u) } }
Mengirim beberapa perintah sekaligus
Batching API memungkinkan klien mengirim beberapa perintah perangkat Home API dalam satu payload. Perintah dikelompokkan ke dalam satu payload dan dieksekusi secara paralel, mirip dengan cara seseorang membuat otomatisasi Home API menggunakan node paralel, seperti contoh Buka tirai sebelum matahari terbit. Namun, Batching API memungkinkan perilaku yang lebih kompleks dan canggih daripada Automation API, seperti kemampuan untuk memilih perangkat secara dinamis saat runtime sesuai dengan kriteria apa pun.
Perintah dalam satu batch dapat menargetkan beberapa karakteristik di beberapa perangkat, di beberapa ruangan, di beberapa struktur.
Mengirim perintah dalam batch memungkinkan perangkat melakukan tindakan secara bersamaan, yang tidak mungkin dilakukan saat perintah dikirim secara berurutan dalam permintaan terpisah. Perilaku yang dicapai menggunakan perintah batch memungkinkan developer menetapkan status sekelompok perangkat agar sesuai dengan status gabungan yang telah ditentukan sebelumnya.
Menggunakan Batching API
Ada tiga langkah dasar yang terlibat dalam memanggil perintah melalui Batching API:
- Panggil metode
Home.sendBatchedCommands()
. - Dalam isi blok
sendBatchedCommands()
, tentukan perintah yang akan disertakan dalam batch. - Periksa hasil perintah yang dikirim untuk melihat apakah perintah tersebut berhasil atau gagal.
Panggil metode sendBatchedCommands()
Panggil
metode
Home.sendBatchedCommands()
. Di balik layar, metode ini menyiapkan ekspresi lambda dalam konteks batch khusus.
home.sendBatchedCommands() {
Menentukan perintah batch
Dalam isi blok sendBatchedCommands()
, isi batchable
commands. Perintah yang dapat di-batch adalah versi "shadow" dari perintah Device API yang ada yang dapat digunakan dalam konteks batch, dan diberi nama dengan akhiran Batchable
yang ditambahkan. Misalnya, perintah
LevelControl
trait
moveToLevel()
memiliki perintah serupa bernama
moveToLevelBatchable()
.
Contoh:
val response1 = add(command1)
val response2 = add(command2)
Batch akan otomatis dikirim setelah semua perintah ditambahkan ke konteks batch dan eksekusi telah keluar dari konteks.
Respons dicatat dalam
objek DeferredResponse<T>
.
Instance DeferredResponse<T>
dapat dikumpulkan ke dalam objek jenis apa pun, seperti
Collection
, atau class data yang Anda tentukan. Jenis objek apa pun yang Anda pilih untuk mengumpulkan respons adalah jenis objek yang ditampilkan oleh sendBatchedCommands()
. Misalnya, konteks batch dapat menampilkan dua instance
DeferredResponse
dalam Pair
:
val (response1, response2) = homeClient.sendBatchedComamnds {
val response1 = add(someCommandBatched(...))
val response2 = add(someOtherCommandBatched(...))
Pair(response1, response2)
}
Atau, konteks batch dapat menampilkan instance DeferredResponse
dalam class data kustom:
// Custom data class
data class SpecialResponseHolder(
val response1: DeferredResponse<String>,
val response2: DeferredResponse<Int>,
val other: OtherResponses
)
data class OtherResponses(...)
Periksa setiap respons
Di luar blok sendBatchedCommands()
, periksa respons untuk menentukan
apakah perintah yang sesuai berhasil atau gagal. Hal ini dilakukan dengan memanggil
DeferredResponse.getOrThrow()
, yang:
- menampilkan hasil perintah yang dijalankan,
- atau, jika cakupan batch belum selesai atau perintah tidak
berhasil, akan memunculkan error.
Anda hanya boleh memeriksa hasil di luar cakupan lambda sendBatchedCommands()
Contoh
Misalnya, Anda ingin membuat aplikasi yang menggunakan Batching API untuk menyiapkan adegan 'selamat malam' yang mengonfigurasi semua perangkat di rumah untuk malam hari, saat semua orang tertidur. Aplikasi ini akan mematikan lampu dan mengunci pintu depan dan belakang.
Berikut salah satu cara untuk menyelesaikan tugas ini:
val lightDevices: List<OnOffLightDevice>
val doorlockDevices: List<DoorLockDevice>
// Send all the commands
val responses: List<DeferredResponse<Unit>> = home.sendBatchedCommands {
// For each light device, send a Batchable command to turn it on
val lightResponses: List<DeferredResponse<Unit>> = lightDevices.map { lightDevice ->
add(lightDevice.standardTraits.onOff.onBatchable())
}
// For each doorlock device, send a Batchable command to lock it
val doorLockResponse: List<DeferredResponse<Unit>> = doorlockDevices.map { doorlockDevice ->
add(doorlockDevice.standardTraits.doorLock.lockDoorBatchable())
}
lightResponses + doorLockResponses
}
// Check that all responses were successful
for (response in responses) {
response.getOrThrow()
}