As APIs Structure podem ser acessadas pelas APIs Home para iOS.
Para trabalhar com as APIs Structure, primeiro importe o pacote GoogleHomeSDK para
seu app:
import GoogleHomeSDK
Tratamento de erros
Alguns métodos nas APIs Home geram um
HomeError. Por isso, recomendamos usar um bloco do-catch para capturar
HomeError nessas chamadas.
Ao processar HomeError, verifique os campos code e message
para saber o que deu errado.
Qualquer erro não tratado vai causar falhas no app.
Para mais informações, consulte Tratamento de erros.
API Structure
Home representa o Home Graph e é o ponto de entrada da API Structure.
Ele fornece referências a estruturas, salas e dispositivos.
Structure representa uma estrutura no seu gráfico residencial. Ele dá acesso a metadados de estrutura, como id e name.
Use structures() para
receber todas as estruturas na sua conta. As estruturas são retornadas na forma de um
Query, que oferece uma escolha
de maneiras de consumir os dados:
| API | Descrição |
|---|---|
stream() |
Retorna um Publisher que emite cada objeto individualmente à medida que as mudanças ocorrem. |
batched() |
Retorna um Publisher que emite o resultado atual como um Set de objetos. Cada Set emitido representa o estado atual do gráfico de objetos. |
list() |
Retorna o resultado atual como um Set de objetos. |
A chamada structures().list() pode não retornar imediatamente um conjunto válido de
estruturas. Se o app for reativo e chamar stream() para se inscrever em
todas as mudanças de estrutura para acionar a interface, uma lista válida de estruturas será
retornada eventualmente. Há outras situações em que uma lista de estruturas vazia pode ser retornada, por exemplo, se o smartphone do usuário perder a conectividade ou se ele revogar as permissões do seu app. Não se esqueça de processar esses casos no seu app.
@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)
Chamadas de exemplo de estrutura
Receber um conjunto de estruturas
Chamar list() em um Query<Structure> retorna o conjunto mais recente de elementos:
// Get a stream of all structures accessible to the user let allStructuresChanges = self.home.structures() let allStructures = try? await allStructuresChanges.list()
Ao projetar um app reativo, use chamadas batched() e stream() em vez de list(), porque elas produzem dados automaticamente quando o gráfico inicial muda.
Acessar propriedades da estrutura
Com a lista de estruturas em mãos, você pode acessar as propriedades delas:
// 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) ")
Encontrar uma estrutura pelo nome
Se você souber o nome de uma estrutura, também poderá acessá-la usando a propriedade name:
do { structure1 = try await home.structures().list().first(where: { $0.name == "Main House" }) } catch let _ as HomeError { // Code for handling the exception }
A partir daí, é possível acessar as propriedades, os cômodos e os dispositivos de cada estrutura.
Trabalhar com várias estruturas
Para usar mais de uma estrutura, receba uma referência separada para cada uma delas:
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 }
Salas
Uma sala contém um grupo de dispositivos. Uma sala sempre faz parte de uma estrutura, e uma estrutura pode ter várias salas. Remover um cômodo de uma estrutura não remove os dispositivos dele da estrutura. No entanto, se o ambiente for excluído, os dispositivos nele vão ficar sem atribuição.
Use Home.rooms() para
recuperar todos os ambientes na conta e roomID = device.roomID para
mostrar os dispositivos correspondentes em cada ambiente.
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)
Chamadas de trecho
Receber uma lista de salas
Usando a classe Home, você pode acessar uma lista de salas e as propriedades delas:
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) ")
Criar uma sala
Para criar um novo ambiente em um 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 }
Excluir um ambiente
Ou, se preferir, exclua uma sala:
val roomToDelete = structure.rooms().list().filter { it.name == "room_id1" }.firstOrNull() structure.deleteRoom(roomToDelete!!)
Também é possível excluir uma sala usando o ID dela:
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 } }
Se um ambiente com dispositivos for excluído, eles ainda estarão na estrutura, mas não atribuídos a um ambiente.
Mover dispositivos para outro ambiente
Com o Structure, também é possível mover um dispositivo para outro ambiente:
do { try await structure.move(device: light, to: room) } catch let _ as HomeError { // Code for handling the exception }
Mudar o nome de um ambiente
Chame o método
setName(_:)
para mudar o nome de um ambiente:
let updatedRoom = try await theRoom.setName("new room name")
Ao mudar o nome de uma sala, a struct Room original permanece a mesma, e
a mudança é refletida no objeto Room atualizado retornado.
Os nomes serão truncados se ultrapassarem o limite de 60 pontos de código Unicode (caracteres), e nenhum erro será gerado. Os desenvolvedores são responsáveis por processar nomes longos e, por exemplo, podem decidir se querem informar aos usuários que os nomes serão truncados.
Grupos de dispositivos
Um grupo de dispositivos representa uma coleção de dispositivos definida pelo usuário em uma única estrutura.
Assim como as salas físicas, os grupos de dispositivos pertencem a uma única estrutura. Mas, ao contrário dos ambientes, os grupos de dispositivos são agrupamentos lógicos. Um dispositivo pode pertencer a vários grupos de dispositivos ao mesmo tempo. Os grupos de dispositivos podem conter até 100 dispositivos.
Os grupos de dispositivos são representados pela entidade Group, que é diferente de
HomeDevice.
Receber uma lista de grupos de dispositivos
Para observar todos os grupos de dispositivos em uma estrutura:
for await groups in structure.deviceGroups.batched() {
for group in groups {
print("Found group: \(group.name) with ID: \(group.id)")
}
}
Criar um grupo de dispositivos
Use o GroupManagementTrait na estrutura para criar um grupo de dispositivos:
let groupsManagementTrait = try await structure.traits(Google.GroupManagementTrait)
let _ = try await groupsManagementTrait.createUserDefinedGroup(withName: "Kitchen Lights",
withDevices: [light1, light2])
Gerenciar associação a grupos
Para adicionar participantes a um grupo:
let groupManagementTrait = try await structure.traits(Google.GroupManagementTrait.self)
groupManagementTrait.addGroupMembers(
groupObjectId: group.id,
memberDeviceObjectIds = [light3.id],
)
Para remover participantes de um grupo:
let groupManagementTrait = try await structure.traits(Google.GroupManagementTrait.self)
_ = try await groupManagementTrait.removeGroupMembers(
groupObjectId: group.id,
memberDeviceObjectIdsArray: Array(removedIDs)
Mudar o nome de um grupo de dispositivos
Para renomear um grupo de dispositivos, atualize o campo name do GroupTrait:
let groupTrait = group.traits.get(Google.GroupTrait.self)
_ = try await groupTrait.update { $0.name = "Movie Corner" }
Excluir um grupo de dispositivos
Para excluir um grupo de dispositivos de uma estrutura:
let groupManagementTrait = try await structure.traits.get(Google.GroupManagementTrait.self)
_ = try await groupManagementTrait.deleteGroup(groupObjectId: group.id)