As APIs de dispositivo podem ser acessadas pelas APIs Home para iOS. Importe os seguintes pacotes para seu app:
import GoogleHomeSDK
import GoogleHomeTypes
Para mais informações, consulte Modelo de dados no iOS.
Tratamento de erros
Alguns métodos nas APIs Home geram um
HomeError
. Por isso, recomendamos que você use 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 uma falha no app.
Para mais informações, consulte Tratamento de erros.
Consulte Enviar um comando para um dispositivo para ver um exemplo.
Exemplos de chamadas
Acessar uma lista de dispositivos
Com uma referência ao objeto Home
, invoque
devices()
para receber um
Query
de dispositivos
acessíveis.
Chame o método
batched()
do Query
, que emite um conjunto que reflete o estado atual da casa a cada
mudança nos metadados do dispositivo. Ou chame
Query.list()
para receber um
instantâneo dos dispositivos disponíveis. Esse é um método de conveniência que se inscreve no
fluxo batched()
e retorna o primeiro valor emitido.
Query.stream()
produz um fluxo que emite novos valores em mudanças de metadados do dispositivo, como
nome, sala ou estrutura. Internamente, isso usa batched()
e emite apenas as propriedades alteradas.
// Get a list of all devices accessible to the user let homeDevices = try await self.home.devices().list()
Lá, os estados de cada dispositivo ficam acessíveis, e os comandos compatíveis podem ser enviados a eles.
Acessar os tipos de dispositivo
Para saber os tipos de dispositivo associados a um dispositivo, leia a propriedade types
do dispositivo, que retorna um
DeviceTypeController
.
Chame DeviceTypeController.subscribe(_:)
para se inscrever em atualizações de um
tipo de dispositivo específico:
let devices = try await self.home.devices().list() if let device = devices.first(where: { $0.id == myDeviceId }) { var receivedUpdate1 = false var receivedUpdate2 = false device.types.subscribe(OnOffLightDeviceType.self) .assertNoFailure() .sink { device in if !receivedUpdate1 { receivedUpdate1 = true Task { try await device.matterTraits.onOffTrait?.on() } return } if !receivedUpdate2 { receivedUpdate2 = true return } fatalError("Received unexpected update") } }
Se o dispositivo não for compatível com o tipo especificado, ele vai retornar um Empty
Publisher
que será concluído imediatamente.
Se o dispositivo for compatível com um tipo específico, você poderá receber um identificador desse
tipo chamando get()
:
if let device = devices.first(where: { $0.id == myDeviceId }) { let deviceType = await device.types.get(OnOffLightDeviceType.self) }
Se o dispositivo não for compatível com o tipo especificado, ele vai retornar nil
.
Chame
DeviceTypeController.subscribeAll()
para receber um Publisher
de
DeviceTypeCollection
.
Com essa classe, é possível verificar se o dispositivo tem um tipo
específico:
if let device = devices.first(where: { $0.id == myDeviceId }) { device.types.subscribeAll() .assertNoFailure() .sink { types in let lightDeviceType = types[OnOffLightDeviceType.self] let fanDeviceType = types[FanDeviceType.self] } }
Receber uma característica de tipo de dispositivo
Os tipos de dispositivo são o ponto de entrada para leitura de características, já que decompõem um dispositivo em partes funcionais (como endpoints em Matter).
Elas também consideram colisões de características caso um dispositivo tenha dois tipos, ambos com a mesma característica. Por exemplo, se um dispositivo for um alto-falante e uma luz dimerizável, ele terá dois traços de ativação/desativação e dois de controle de nível.
Outro tipo de conflito de traços pode ocorrer quando um dispositivo tem dois traços com o mesmo nome. Por exemplo, onOff
pode se referir a uma instância da
característica padrão OnOff
ou a uma instância de uma
característica OnOff
definida pelo fabricante. Para eliminar qualquer ambiguidade em relação a qual característica é pretendida, faça referência a uma característica usando uma das duas coleções de características em cada tipo de dispositivo.
Para características padrão, ou seja, aquelas análogas aos clusters padrão Matter, use matterTraits
. Por exemplo, para receber uma característica específica do tipo de dispositivo "Luz dimerizável":
if let dimmableLightDeviceType = await device.types.get(DimmableLightDeviceType.self) { // Accessing standard trait on the type. let levelControlTrait = dimmableLightDeviceType.matterTraits.levelControlTrait.self }
Para características do Google, use googleTraits
:
if let doorbellDeviceType = await device.types.get(GoogleDoorbellDeviceType.self) { // Accessing Google trait on the type. let doorbellPressTrait = doorbellDeviceType.googleTraits.doorbellPressTrait.self }
Para acessar uma característica específica do fabricante, faça referência a ela usando a propriedade traits
, mas preceda com o nome do pacote do fabricante:
let deviceType = await device1?.types.get(OnOffLightDeviceType.self) // Accessing custom trait on the type. if let spinnerTrait = deviceType?.traits[ExampleOrganization.SpinnerTrait.self] { let rpmVal = spinnerTrait.attributes.rpm }
Ler o estado de um dispositivo
Confira este exemplo de verificação do atributo OnOff
da característica
liga/desliga do dispositivo:
let lightDevices = devices.filter { $0.types.contains(OnOffLightDeviceType.self) } let light1 = lightDevices.first let lightDeviceTypeOptional = await light1?.types.get(OnOffLightDeviceType.self) if let onOffTrait = lightDeviceTypeOptional?.matterTraits.onOffTrait { let onOffVal = onOffTrait.attributes.onOff }
Receber uma lista de dispositivos com uma característica específica
Para receber uma lista de dispositivos com um traço específico, é necessário iterar pelos dispositivos, pelos tipos de dispositivo de cada um e pelos traços de cada tipo de dispositivo. Por exemplo, para receber uma lista de dispositivos na casa que têm o traço On/Off:
// Get all light devices that support levelControl var levelControlDevices: [HomeDevice] = [] var allDevices = try await home.devices().list() for device in allDevices { if let deviceType = await device.types.get(OnOffLightDeviceType.self) { if deviceType.traits.contains(Matter.LevelControlTrait.self) { levelControlDevices.append(device) } } }
Consulte Índice de traços no iOS para uma lista completa de traços disponíveis nas APIs Home.
Receber uma lista de dispositivos com tipos semelhantes
Para ver uma lista de dispositivos que representam todas as luzes de uma casa:
// Get a list of devices with similar device types (lights) let lightDevices = try await self.home.devices().list().compactMap { $0.types.contains(DimmableLightDeviceType.self) || $0.types.contains(OnOffLightDeviceType.self) || $0.types.contains(ColorTemperatureLightDeviceType.self) || $0.types.contains(ExtendedColorLightDeviceType.self) }
Há vários tipos de dispositivos nas APIs Home que podem representar um tipo de dispositivo principal. Por exemplo, não há um tipo de dispositivo "Luz". Em vez disso, há quatro tipos de dispositivos diferentes que podem representar uma luz, conforme mostrado no exemplo anterior. Portanto, para ter uma visão abrangente de um tipo de dispositivo de nível superior em uma casa, é necessário incluir vários tipos de dispositivos.
Consulte a lista completa de tipos de dispositivos compatíveis com iOS e os recursos disponíveis nas APIs Home.
Encontrar o nome, o ID do fornecedor ou o ID do produto de um dispositivo
O traço BasicInformationTrait
inclui informações como ID do fornecedor, ID do produto, nome do produto e o
número de série de um dispositivo:
guard let vendorName = basicInfoTrait.attributes.vendorName else { fatalError("Failed to get vendorName") } guard let vendorID = basicInfoTrait.attributes.vendorID else { fatalError("Failed to get vendorID") } guard let productID = basicInfoTrait.attributes.productID else { fatalError("Failed to get productID") }
Identificação de dispositivos de nuvem para nuvem para fabricantes de dispositivos
Se você é um fabricante de dispositivos e cria dispositivos Cloud-to-cloud,
para identificar seus
dispositivos Cloud-to-cloud usando o
traço BasicInformation
, inclua estes campos de string na
resposta SYNC
deles:
A Connectivity Standards Alliance (CSA) emitiu o ID do fornecedor:
"matterOriginalVendorId": "0xfff1",
Um identificador de produto que identifica de forma exclusiva um produto de um fornecedor:
"matterOriginalProductId": "0x1234",
Um identificador exclusivo do dispositivo, construído de maneira específica do fabricante:
"matterUniqueId": "matter-device-id",
Ao inserir esses campos de string, use os IDs de Matter
fornecedor e produto, se você os tiver. Se você não for um membro da CSA e não tiver recebido esses IDs, deixe os campos matterOriginalVendorId
e matterOriginalProductId
em branco e forneça o matterUniqueId
como identificador.
O exemplo de resposta SYNC mostra o uso destes campos:
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"payload": {
"agentUserId": "1836.15267389",
"devices": [
{
"id": "456",
"type": "action.devices.types.LIGHT",
"traits": [
"action.devices.traits.OnOff",
"action.devices.traits.Brightness",
"action.devices.traits.ColorSetting",
],
"willReportState": true,
"deviceInfo": { ... },
"matterOriginalVendorId": "0xfff1",
"matterOriginalProductId": "0x1234",
"matterUniqueId": "matter-device-id",
"otherDeviceIds": [
{
"deviceId": "local-device-id",
}
]
}
]
}
}
Para mais informações, consulte a
documentação do Cloud-to-cloud SYNC
.
Metadados de dispositivos e características
Os dispositivos e características nas APIs Home têm metadados associados a eles, o que pode ajudar a gerenciar a experiência do usuário em um app.
Cada característica nas APIs Home contém uma propriedade
sourceConnectivity
com informações sobre o status on-line e a localidade de uma característica
(roteamento local ou remoto).
Receber o tipo principal de um dispositivo
Alguns dispositivos podem apresentar vários tipos de dispositivos pelas APIs Home. Para garantir que os usuários tenham as opções adequadas em um app (como controle de dispositivos e automações sugeridas) para os dispositivos deles, é útil verificar se um tipo de dispositivo é o principal.
if let deviceType = await device?.types.get(HumiditySensorDeviceType.self) { if deviceType.metadata.isPrimaryType { print("Humidity Sensor is the primary type on this device.") } else { print("Humidity Sensor isn't the primary type on this device.") } }
Verificar se uma característica está on-line
Leia a propriedade connectivityState
para verificar a conectividade de um traço:
let levelControlConnectivity = levelControlTrait.metadata.sourceConnectivity .connectivityState
Algumas características, geralmente do Google smart home, podem aparecer off-line se o dispositivo não tiver conectividade com a Internet. Isso acontece porque esses traços são baseados na nuvem e não têm roteamento local.
Verificar a conectividade de um dispositivo
A conectividade de um dispositivo é verificada no nível do tipo de dispositivo, porque alguns dispositivos são compatíveis com vários tipos. O estado retornado é uma combinação dos estados de conectividade de todas as características do dispositivo.
let lightConnectivity = dimmableLightDeviceType.metadata.sourceConnectivity .connectivityState
Um estado partiallyOnline
pode ser observado no caso de tipos de dispositivos mistos quando não há conectividade com a Internet. As características padrão do Matter ainda podem estar on-line devido ao roteamento local, mas as características baseadas na nuvem vão ficar off-line.
Verificar o roteamento de rede de uma característica
A localidade de uma característica também está disponível nas APIs Home. O
dataSourceLocality
indica se a característica é roteada remotamente (pela
nuvem), localmente (por um hub local) ou de ponto a ponto (diretamente de
dispositivo para dispositivo, sem hub).
O valor de localidade desconhecida unspecified
é possível, por exemplo, enquanto um
app está sendo inicializado e ainda não chegou a um hub ou servidor para conectividade
do dispositivo. Esses dispositivos não estão acessíveis e vão falhar em solicitações de interação
de comandos ou eventos. Cabe ao cliente determinar como
lidar com esses dispositivos.
let levelControlLocality = levelControlTrait.metadata.sourceConnectivity .dataSourceLocality
Verificar o roteamento de rede de um dispositivo
Assim como a conectividade, a localidade é verificada no nível do tipo de dispositivo. O estado retornado é uma combinação da localidade de todas as características do dispositivo.
let lightLocality = dimmableLightDeviceType.metadata.sourceConnectivity.dataSourceLocality
Um estado de mixed
pode ser observado em um cenário semelhante ao da conectividade partiallyOnline
: alguns traços são baseados na nuvem, enquanto outros são locais.
Mudar o nome de um dispositivo
Chame o método
setName(_:)
para mudar o nome de um dispositivo:
let updatedDevice = try await theDevice.setName("new device name")
Ao mudar o nome de um dispositivo, a struct HomeDevice
original permanece a mesma, e a mudança é refletida no objeto HomeDevice
atualizado retornado.
Lista de APIs
Depois que uma instância de
Home
é criada, as
seguintes APIs de dispositivo ficam acessíveis por ela:
API | Descrição |
---|---|
device(id:) |
Retorna um Publisher para o dispositivo especificado que emite o estado do dispositivo sempre que ele muda. |
devices() |
Recebe todos os dispositivos em todas as estruturas na Conta do Google. Retorna um Query<HomeDevice> que oferece mais opções de recuperação e filtragem. |
Depois de ter um
HomeDevice
, as seguintes
APIs poderão ser acessadas por ele:
API | Descrição |
---|---|
id |
O ID exclusivo do sistema do dispositivo. |
name |
O nome do dispositivo fornecido pelo usuário. |
structureID |
O ID da estrutura a que o dispositivo está atribuído. Retorna um String? . |
roomID |
O ID da sala a que o dispositivo está atribuído. Retorna um String? . |
types |
Receba um tipo específico ou todos os tipos disponíveis no dispositivo. |
isMatterDevice |
Se o dispositivo for compatível com Matter. |
sourceConnectivity |
A conectividade de origem do dispositivo, representando estados de conectividade agregados e localidade de rede dos traços do dispositivo. |