Structure API dapat diakses melalui Home API untuk iOS.
Untuk menggunakan Structure API, impor paket GoogleHomeSDK terlebih dahulu ke
aplikasi Anda:
import GoogleHomeSDK
Penanganan error
Beberapa metode di Home API menampilkan
HomeError, jadi sebaiknya gunakan blok do-catch untuk menangkap
HomeError pada panggilan tersebut.
Saat menangani HomeError, periksa kolom code dan message-nya
untuk mengetahui penyebab masalahnya.
Error yang tidak ditangani akan menyebabkan aplikasi Anda error.
Untuk mengetahui informasi selengkapnya, lihat Penanganan error.
Structure API
Home mewakili Home Graph, dan merupakan titik entri ke Structure API.
API ini memberikan referensi ke struktur, ruangan, dan perangkat.
Structure mewakili struktur di Home Graph Anda. API ini memberikan akses ke
metadata struktur seperti id dan name.
Gunakan structures() untuk
mendapatkan semua struktur di akun Anda. Struktur ditampilkan dalam bentuk
Query, yang menawarkan pilihan
cara menggunakan datanya:
| API | Deskripsi |
|---|---|
stream() |
Menampilkan Publisher yang memunculkan setiap objek satu per satu saat terjadi perubahan. |
batched() |
Menampilkan Publisher yang memunculkan hasil saat ini sebagai Set objek. Setiap Set yang dimunculkan mewakili status grafik objek saat ini. |
list() |
Menampilkan hasil saat ini sebagai Set objek. |
Panggilan structures().list() mungkin tidak langsung menampilkan kumpulan struktur yang valid. Jika aplikasi Anda reaktif dan memanggil stream() untuk berlangganan
semua perubahan struktur untuk menggerakkan UI, daftar struktur yang valid pada akhirnya
akan ditampilkan. Ada situasi lain saat daftar struktur kosong
dapat ditampilkan, misalnya jika ponsel pengguna kehilangan konektivitas atau jika
pengguna telah mencabut izin ke aplikasi Anda. Anda harus memastikan untuk menangani kasus ini
di aplikasi Anda.
@Published public private(set) var structures: [Structure] = []
private var structuresCancellable: AnyCancellable?
self.structuresCancellable = home
.structures()
.batched()
.receive(on: DispatchQueue.main)
.map { Array($0) }
.catch {
// Failed to load structures
return Just([Structure]())
}
.assign(to: \.structures, on: self)
Contoh panggilan Struktur
Mendapatkan kumpulan struktur
Memanggil list() pada Query<Structure> akan menampilkan Set elemen terbaru:
// Get a stream of all structures accessible to the user let allStructuresChanges = self.home.structures() let allStructures = try? await allStructuresChanges.list()
Saat mendesain aplikasi reaktif, Anda sebaiknya menggunakan panggilan batched() dan stream(),
bukan list(), karena panggilan ini otomatis menghasilkan data saat
grafik rumah berubah.
Mendapatkan properti struktur
Dengan daftar struktur yang ada, Anda dapat mengakses propertinya:
// Get a stream of changes taking place on a structure. let structureChanges = try await home.structures().list().filter { $0.id == structureID } // Get a snapshot of the structure. let structure = structureChanges.first! // Get structure properties print("id \(structure.id) ") print("name \(structure.name) ")
Menemukan struktur berdasarkan nama
Jika mengetahui nama struktur, Anda juga dapat mengaksesnya menggunakan properti name:
do { structure1 = try await home.structures().list().first(where: { $0.name == "Main House" }) } catch let _ as HomeError { // Code for handling the exception }
Dari sana, properti, ruangan, dan perangkat untuk setiap struktur dapat diakses.
Menggunakan beberapa struktur
Untuk menggunakan lebih dari satu struktur, dapatkan referensi terpisah untuk setiap struktur:
var structure1: Structure! var structure2: Structure! do { structure1 = try await home.structures().list().first(where: { $0.name == "Main House" }) } catch let _ as HomeError { // Code for handling the exception } do { structure2 = try await home.structures().list().first(where: { $0.name == "Guest Cottage" }) } catch let _ as HomeError { // Code for handling the exception }
Kamar
Ruangan berisi sekelompok perangkat. Ruangan selalu menjadi bagian dari struktur dan struktur dapat memiliki beberapa ruangan. Menghapus ruangan dari struktur tidak akan menghapus perangkat di ruangan tersebut dari struktur. Namun, jika ruangan dihapus, perangkat di ruangan tersebut akan menjadi tidak ditetapkan.
Gunakan Home.rooms() untuk
mengambil semua ruangan di akun, lalu gunakan roomID = device.roomID untuk
menampilkan perangkat yang sesuai di setiap ruangan.
self.home.rooms().batched()
.combineLatest(self.home.devices().batched())
.receive(on: DispatchQueue.main)
.catch { error in
// Failed to load rooms and devices
return Just((Set<Room>(), Set<HomeDevice>()))
}
.map { rooms, devices in
var devicesByRoom = [Room: [HomeDevice]]()
for room in rooms where room.structureID == currentStructureID {
devicesByRoom[room] = devices.filter { $0.roomID == room.id }
}
return devicesByRoom
}.assign(to: &self.$devicesByRoom)
Panggilan Ruang Sampel
Mendapatkan daftar ruang
Dengan menggunakan class Home, Anda bisa mendapatkan daftar ruang dan mengakses
properti untuk ruang tersebut:
let allRoomsChanges = self.home.rooms() let allRooms = try await allRoomsChanges.list() let room = allRooms.first! XCTAssertTrue(allRooms.contains(room)) print("id \(room.id) ") print("name \(room.name) ")
Buat ruang
Untuk membuat ruang baru di Structure:
let testName = "Test Room Name" var newRoom: Room! do { newRoom = try await structure.createRoom(name: testName) XCTAssertNotNil(newRoom) } catch let _ as HomeError { // Code for handling the exception }
Menghapus ruangan
Atau, Anda dapat menghapus ruang:
val roomToDelete = structure.rooms().list().filter { it.name == "room_id1" }.firstOrNull() structure.deleteRoom(roomToDelete!!)
Anda juga dapat menghapus ruang menggunakan ID-nya:
let roomToDelete = allRooms.first(where: { $0.id == room.id }) if let roomToDelete1 = roomToDelete { do { try await structure.deleteRoom(roomToDelete1) } catch let _ as HomeError { // Code for handling the exception } }
Jika ruangan yang memiliki perangkat dihapus, perangkat akan tetap berada dalam struktur, tetapi tidak lagi ditetapkan ke ruangan.
Memindahkan perangkat ke ruangan lain
Structure juga memungkinkan Anda memindahkan perangkat ke ruangan lain:
do { try await structure.move(device: light, to: room) } catch let _ as HomeError { // Code for handling the exception }
Mengubah nama ruangan
Panggil metode
setName(_:)
untuk mengubah nama ruang:
let updatedRoom = try await theRoom.setName("new room name")
Saat mengubah nama ruang, struct Room asli tetap sama dan
perubahan akan terlihat dalam objek Room yang diperbarui dan ditampilkan.
Nama akan dipotong jika melebihi batas 60 poin kode Unicode (karakter) dan tidak akan ada error yang ditampilkan. Developer bertanggung jawab untuk menangani nama yang panjang dan, misalnya, dapat memutuskan apakah mereka ingin memberi tahu pengguna bahwa nama akan dipotong.
Grup perangkat
Grup perangkat mewakili kumpulan perangkat yang ditentukan pengguna dalam satu struktur. Keanggotaan grup dipertahankan di layanan Google dan dapat dilihat oleh anggota lain dari struktur dan aplikasi lain yang memiliki akses ke struktur.
Seperti ruangan fisik, grup perangkat termasuk dalam satu struktur. Namun, tidak seperti ruangan, grup perangkat adalah grup logis. Perangkat dapat termasuk dalam beberapa grup perangkat secara bersamaan. Grup perangkat dapat berisi hingga 100 perangkat.
Grup perangkat diwakili oleh entitasDeviceGroup, yang berbeda dengan HomeDevice. Untuk berinteraksi
dengan grup perangkat, sertakan jenis dan karakteristik perangkat yang relevan saat
mengonfigurasi
ReferencedAutomationTypes
di Home.configure, beserta
karakteristik
GroupTrait,
GroupManagementTrait,
dan
GroupMembershipTrait.
Anda dapat berinteraksi dengan perangkat dalam grup dengan melakukan iterasi pada
perangkat anggotanya secara langsung (lihat
Berinteraksi dengan perangkat anggota grup) atau dengan menargetkan
bagian jenis perangkat di DeviceGroup (lihat
Mengontrol grup perangkat).
Mendapatkan daftar grup perangkat
Untuk mengkueri semua grup perangkat di rumah:
let groups = try await home.entities(DeviceGroup.self).list()
for group in groups {
let groupTrait = await group.traits.get(Google.GroupTrait.self)
let name = groupTrait?.attributes.name ?? "Device Group"
print("Found group: \(name) with ID: \(group.id)")
}
Berinteraksi dengan perangkat anggota grup
Melakukan iterasi pada perangkat anggota grup memberi Anda kontrol terperinci atas masing-masing anggota, memungkinkan Anda mengelompokkan perintah dalam satu permintaan, dan memungkinkan Anda menggabungkan atau menulis atribut di seluruh anggota.
Pertama, filter perangkat di rumah dengan memeriksa GroupMembershipTrait setiap perangkat untuk ID grup target:
let allDevices = try await home.devices().list()
var members: [HomeDevice] = []
for device in allDevices {
if let membership = await device.traits.get(
Google.GroupMembershipTrait.self
),
membership.attributes.groupObjectIdsArray.contains(group.id) {
members.append(device)
}
}
Untuk mengirim satu permintaan batch dengan perintah untuk karakteristik di semua anggota grup yang kompatibel:
var onOffTraits: [Matter.OnOffTrait] = []
for device in members {
if let light = await device.types.get(OnOffLightDeviceType.self),
let onOff = light.matterTraits.onOffTrait {
onOffTraits.append(onOff)
}
}
let traitsToUse = onOffTraits
let responses = try await home.sendBatchedCommands { batcher in
return try traitsToUse.map { batcher.add(try $0.onBatchable()) }
}
for response in responses {
try response.getOrThrow()
}
Anda juga dapat memperbarui atribut di semua perangkat anggota yang cocok dalam grup
(misalnya, menetapkan onTransitionTime ke 1 di semua
anggota DimmableLightDeviceType) secara serentak dan menunggu penyelesaian dalam
batas waktu:
try await withThrowingTaskGroup(of: Void.self) { taskGroup in
taskGroup.addTask {
try await Task.sleep(for: .seconds(5))
throw CancellationError()
}
for device in members {
taskGroup.addTask {
guard let light = await device.types.get(DimmableLightDeviceType.self),
let levelControl = light.matterTraits.levelControlTrait,
levelControl.attributes.$onTransitionTime.isSupported
else { return }
_ = try await levelControl.update {
$0.setOnTransitionTime(1)
}
}
}
for _ in 0..<members.count {
try await taskGroup.next()
}
taskGroup.cancelAll()
}
Untuk menggabungkan atribut di seluruh anggota grup, seperti menemukan
colorTempPhysicalMaxMireds minimum di semua lampu suhu warna dalam
grup:
var maxMiredsValues: [UInt16] = []
for device in members {
if let light = await device.types.get(ColorTemperatureLightDeviceType.self),
let mireds = light.matterTraits.colorControlTrait?.attributes
.colorTempPhysicalMaxMireds {
maxMiredsValues.append(mireds)
}
}
let minMaxMireds = maxMiredsValues.min()
Membuat grup perangkat
Gunakan
GroupManagementTrait
pada struktur untuk membuat grup perangkat:
let groupsManagementTrait =
try await structure.traits(Google.GroupManagementTrait)
let _ = try await groupsManagementTrait.createUserDefinedGroup(
withName: "Kitchen Lights",
withDevices: [light1, light2]
)
Mengelola keanggotaan grup
Untuk menambahkan anggota ke grup yang ada:
let groupManagementTrait =
try await structure.traits(Google.GroupManagementTrait.self)
groupManagementTrait.addGroupMembers(
groupObjectId: group.id,
memberDeviceObjectIds = [light3.id],
)
Untuk menghapus anggota dari grup:
let groupManagementTrait =
try await structure.traits(Google.GroupManagementTrait.self)
_ = try await groupManagementTrait.removeGroupMembers(
groupObjectId: group.id,
memberDeviceObjectIdsArray: Array(removedIDs)
)
Mengubah nama grup perangkat
Untuk mengganti nama grup perangkat, perbarui kolom name GroupTrait:
let groupTrait = group.traits.get(Google.GroupTrait.self)
_ = try await groupTrait.update { $0.name = "Movie Corner" }
Menghapus grup perangkat
Untuk menghapus grup perangkat dari struktur:
let groupManagementTrait =
try await structure.traits.get(Google.GroupManagementTrait.self)
_ = try await groupManagementTrait.deleteGroup(groupObjectId: group.id)