As APIs do dispositivo podem ser acessadas pelas APIs Home para iOS. Importe os seguintes pacotes para o 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 uma
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 processado vai resultar em falha no app.
Para mais informações, consulte Como processar erros.
Consulte Enviar um comando para um dispositivo para conferir um exemplo.
Exemplos de chamadas
Acessar uma lista de dispositivos
Com uma referência ao objeto Home
, invoque
devices()
para receber uma
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 de metadados do dispositivo. Ou chame
Query.list()
para conferir uma
imagem 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 nas mudanças de metadados do dispositivo, como
nome, sala ou estrutura. Internamente, ele 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()
A partir daí, os estados de cada dispositivo ficam acessíveis, e os comandos compatíveis podem ser enviados para o dispositivo.
Conferir os tipos de dispositivo
Para receber 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 oferecer suporte a um tipo específico, você poderá acessar esse
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 retornará nil
.
Chame
DeviceTypeController.subscribeAll()
para receber um Publisher
de
DeviceTypeCollection
.
Essa classe permite 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] } }
Conseguir uma característica de tipo de dispositivo
Os tipos de dispositivo são o ponto de entrada para a leitura de atributos, já que decompõem um dispositivo em partes funcionais (como endpoints em Matter).
Elas também consideram colisões de características no caso de um dispositivo apresentar dois tipos, que podem ter a mesma característica. Por exemplo, se um dispositivo for um alto-falante e uma luz regulável, ele terá duas características de ativação/desativação e duas de controle de nível.
Outro tipo de colisão de elemento pode ocorrer quando um dispositivo tem dois elementos com
o mesmo nome. Por exemplo, onOff
pode se referir a uma instância do
traço OnOff
padrão ou a uma instância de um
traço OnOff
definido pelo fabricante. Para eliminar qualquer possível ambiguidade sobre
qual característica é destinada, faça referência a uma delas em uma das duas coleções
de características em cada tipo de dispositivo.
Para características padrão, ou seja, aquelas que são análogas aos
clusters padrão Matter, use matterTraits
. Por exemplo,
para receber um atributo específico para o tipo de dispositivo de luz regulá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 um atributo específico do fabricante, faça referência a ele usando a propriedade traits
, mas antecipe-o 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
do
traço de ativação/desativação 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 }
Conferir uma lista de dispositivos com um atributo específico
Para receber uma lista de dispositivos com um recurso específico, é necessário iterar sobre os dispositivos, os tipos de dispositivo de cada um deles e os recursos de cada tipo. Por exemplo, para receber uma lista de dispositivos na casa que têm o recurso Ativado/Desativado:
// 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 o Índice de traços no iOS para conferir uma lista completa de traços disponíveis nas APIs Home.
Conferir uma lista de dispositivos com tipos semelhantes
Para conferir 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 do Google Home que podem representar um tipo principal de dispositivo. Por exemplo, não há um tipo de dispositivo "Luz". Em vez disso, há quatro tipos diferentes de dispositivo que podem representar uma luz, conforme mostrado no exemplo anterior. Portanto, para ter uma visão abrangente do tipo de dispositivo de nível superior em uma casa, é necessário incluir vários tipos de dispositivos.
Consulte os tipos de dispositivos compatíveis no iOS para conferir uma lista completa de tipos de dispositivos e as características deles que estão disponíveis nas APIs Home.
Conferir o nome, o ID do fornecedor ou o ID do produto de um dispositivo
O atributo BasicInformationTrait
inclui informações como ID do fornecedor, ID do produto, nome do produto e
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 dispositivo em 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
:
O ID do fornecedor emitido pela Connectivity Standards Alliance (CSA) é:
"matterOriginalVendorId": "0xfff1",
Um identificador de produto que identifica exclusivamente um produto de um fornecedor:
"matterOriginalProductId": "0x1234",
Um identificador exclusivo do dispositivo, que é criado de uma maneira específica do fabricante:
"matterUniqueId": "matter-device-id",
Ao inserir esses campos de string, use os IDs de fornecedor e de produto Matter, se você tiver. Se você não for membro da CSA e não tiver recebido esses IDs, deixe os campos matterOriginalVendorId
e matterOriginalProductId
em branco e informe o matterUniqueId
como identificador.
O exemplo de resposta SYNC mostra o uso desses 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 do dispositivo e do atributo
Os dispositivos e as características nas APIs Home têm metadados associados, que podem ajudar a gerenciar a experiência do usuário em um app.
Cada atributo nas APIs Home contém uma propriedade
sourceConnectivity
, que tem informações sobre o status on-line e a localidade de um atributo
(roteamento local ou remoto).
Conferir o tipo principal de um dispositivo
Alguns dispositivos podem apresentar vários tipos de dispositivos pelas APIs do Google Home. Para garantir que os usuários tenham acesso às opções adequadas em um app (como controle de dispositivo e automações sugeridas) para os dispositivos, é útil verificar se um tipo de dispositivo é o principal do dispositivo.
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 um atributo está on-line
Leia a propriedade connectivityState
para verificar a conectividade de um atributo:
let levelControlConnectivity = levelControlTrait.metadata.sourceConnectivity .connectivityState
Algumas características, geralmente as do Google smart home, podem aparecer off-line se o dispositivo não tiver conectividade à Internet. Isso ocorre porque essas características são baseadas 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 deles oferecem suporte a vários tipos. O estado retornado é uma combinação dos estados de conectividade de todos os traços no dispositivo.
let lightConnectivity = dimmableLightDeviceType.metadata.sourceConnectivity .connectivityState
Um estado de partiallyOnline
pode ser observado no caso de tipos de dispositivos mistos
quando não há conectividade com a Internet. Os atributos padrão
Matter ainda podem estar on-line devido ao roteamento local, mas os atributos baseados na nuvem estarão
off-line.
Verificar o roteamento de rede de um atributo
A localidade de um atributo também está disponível nas APIs Home. O
dataSourceLocality
indica se o atributo é roteado remotamente (pela
nuvem), localmente (por um hub local) ou 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 alcançou um hub ou servidor para conectividade
do dispositivo. Esses dispositivos não podem ser acessados e vão falhar nas solicitações de interação
de comandos ou eventos. Cabe ao cliente determinar como
processar 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 no dispositivo.
let lightLocality = dimmableLightDeviceType.metadata.sourceConnectivity.dataSourceLocality
Um estado de mixed
pode ser observado em um cenário semelhante
ao da conectividade partiallyOnline
: algumas características são baseadas na nuvem
enquanto outras são locais.
Lista de APIs
Depois que uma instância de
Home
é criada, as
seguintes APIs do dispositivo ficam acessíveis:
API | Descrição |
---|---|
device(id:) |
Retorna um Publisher para o dispositivo especificado que emite o estado do dispositivo sempre que ele muda. |
devices() |
Conferir todos os dispositivos em todas as estruturas da 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 vão estar acessíveis:
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 |
Receber um tipo específico ou todos os tipos disponíveis no dispositivo. |
isMatterDevice |
Se o dispositivo tiver backup do Matter. |
sourceConnectivity |
A conectividade de origem do dispositivo, que representa os estados de conectividade agregados e a localidade de rede dos atributos do dispositivo. |