È possibile accedere alle API del dispositivo tramite le API Home per iOS. Importa i seguenti pacchetti nella tua app:
import GoogleHomeSDK
import GoogleHomeTypes
Per maggiori informazioni, consulta Modello dei dati su iOS.
Gestione degli errori
Alcuni metodi nelle API Home generano un'eccezione
HomeError
, pertanto ti consigliamo di utilizzare un blocco do-catch
per rilevare
HomeError
in queste chiamate.
Quando gestisci HomeError
, controlla i campi code
e message
per scoprire cosa è andato storto.
Qualsiasi errore non gestito causerà l'arresto anomalo dell'app.
Per saperne di più, consulta la sezione Gestione degli errori.
Per un esempio, vedi Invio di un comando a un dispositivo.
Chiamate di esempio
Recuperare un elenco di dispositivi
Con un riferimento all'oggetto Home
, richiama devices()
per ottenere un Query
di dispositivi accessibili.
Chiama il metodo Query
's
batched()
che emette un Set che riflette lo stato attuale della casa a ogni
modifica dei metadati del dispositivo. In alternativa, chiama
Query.list()
per ricevere
un'istantanea dei dispositivi disponibili. Si tratta di un metodo pratico che esegue la sottoscrizione allo stream batched()
e restituisce il primo valore emesso.
Query.stream()
produce un flusso che emette nuovi valori in caso di modifiche ai metadati del dispositivo, ad esempio
nome, stanza o struttura. Internamente, utilizza batched()
ed emette solo
le proprietà modificate.
// Get a list of all devices accessible to the user let homeDevices = try await self.home.devices().list()
Da qui, è possibile accedere agli stati di ogni dispositivo e inviare i comandi supportati al dispositivo.
Recuperare i tipi di dispositivo
Per ottenere i tipi di dispositivi associati a un dispositivo, leggi la proprietà types
del dispositivo, che restituisce un DeviceTypeController
.
Chiama il numero DeviceTypeController.subscribe(_:)
per iscriverti agli aggiornamenti per un
tipo di dispositivo specifico:
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 il dispositivo non supporta il tipo specificato, restituisce un Empty
Publisher
che viene completato immediatamente.
Se il dispositivo supporta un tipo specifico, puoi ottenere un handle per quel tipo chiamando get()
:
if let device = devices.first(where: { $0.id == myDeviceId }) { let deviceType = await device.types.get(OnOffLightDeviceType.self) }
Se il dispositivo non supporta il tipo specificato, restituisce nil
.
Chiama
DeviceTypeController.subscribeAll()
per ricevere un Publisher
di
DeviceTypeCollection
.
Questa classe ti consente di verificare se il dispositivo ha un tipo di dispositivo specifico:
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] } }
Recuperare una caratteristica del tipo di dispositivo
I tipi di dispositivo sono il punto di ingresso per la lettura delle caratteristiche, in quanto scompongono un dispositivo nelle sue parti funzionali (come gli endpoint in Matter).
Tengono inoltre conto delle collisioni di tratti nel caso in cui un dispositivo presenti due tipi di dispositivi, entrambi con lo stesso tratto. Ad esempio, se un dispositivo è sia un altoparlante che una luce dimmerabile, avrà due tratti On/Off e due tratti Controllo livello.
Un altro tipo di conflitto di tratti può verificarsi quando un dispositivo ha due tratti con lo stesso nome. Ad esempio, onOff
potrebbe fare riferimento a un'istanza della
caratteristica standard OnOff
oppure a un'istanza di una
caratteristica OnOff
definita dal produttore. Per eliminare qualsiasi potenziale ambiguità
in merito al tratto previsto, fai riferimento a un tratto tramite una delle due raccolte di tratti
su ogni tipo di dispositivo.
Per i tratti standard, ovvero quelli analoghi ai cluster standard Matter, utilizza matterTraits
. Ad esempio,
per ottenere un tratto specifico per il tipo di dispositivo Luce dimmerabile:
if let dimmableLightDeviceType = await device.types.get(DimmableLightDeviceType.self) { // Accessing standard trait on the type. let levelControlTrait = dimmableLightDeviceType.matterTraits.levelControlTrait.self }
Per le caratteristiche di Google, utilizza googleTraits
:
if let doorbellDeviceType = await device.types.get(GoogleDoorbellDeviceType.self) { // Accessing Google trait on the type. let doorbellPressTrait = doorbellDeviceType.googleTraits.doorbellPressTrait.self }
Per accedere a una caratteristica specifica del produttore, fai riferimento alla proprietà traits
, ma anteponi il nome del pacchetto del produttore:
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 }
Leggere lo stato di un dispositivo
Dai un'occhiata a questo esempio di controllo dell'attributo OnOff
dal tratto
On/Off del 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 }
Visualizzare un elenco di dispositivi con una caratteristica specifica
Per ottenere un elenco di dispositivi con una caratteristica specifica, devi scorrere i dispositivi, i tipi di dispositivo di ciascun dispositivo e le caratteristiche di ciascun tipo di dispositivo. Ad esempio, per ottenere un elenco dei dispositivi della casa che hanno tutti la caratteristica 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) } } }
Consulta l'indice delle caratteristiche su iOS per un elenco completo delle caratteristiche disponibili nelle API Home.
Visualizzare un elenco di dispositivi con tipi di dispositivi simili
Per visualizzare un elenco di dispositivi che rappresentano tutte le luci di una 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) }
Nelle API Home esistono più tipi di dispositivi che potrebbero rappresentare un tipo di dispositivo core. Ad esempio, non esiste un tipo di dispositivo "Luce". Esistono invece quattro diversi tipi di dispositivi che potrebbero rappresentare una luce, come mostrato nell'esempio precedente. Pertanto, per ottenere una visione completa del tipo di dispositivo di livello superiore in una casa, devono essere inclusi più tipi di dispositivi.
Consulta l'elenco completo dei tipi di dispositivi e delle relative caratteristiche disponibili nelle API Home nella sezione Tipi di dispositivi supportati su iOS.
Recuperare il nome del fornitore, l'ID fornitore o l'ID prodotto per un dispositivo
Il tratto BasicInformationTrait
include informazioni quali ID fornitore, ID prodotto, nome prodotto e
numero di serie di un 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") }
Identificazione dei dispositivi da cloud a cloud per i produttori di dispositivi
Se sei un produttore di dispositivi e crei dispositivi Cloud-to-cloud,
per identificare i tuoi
dispositivi Cloud-to-cloud tramite
l'attributo BasicInformation
, puoi includere questi campi stringa nella
risposta SYNC
:
La Connectivity Standards Alliance (CSA) ha rilasciato l'ID fornitore:
"matterOriginalVendorId": "0xfff1",
Un identificatore di prodotto che identifica in modo univoco un prodotto di un fornitore:
"matterOriginalProductId": "0x1234",
Un identificatore univoco per il dispositivo, creato in modo specifico per il produttore:
"matterUniqueId": "matter-device-id",
Quando inserisci questi campi stringa, utilizza gli ID fornitore e prodotto Matter, se li hai. Se non sei un membro della CSA e non ti sono stati assegnati questi ID, puoi lasciare vuoti i campi matterOriginalVendorId
e matterOriginalProductId
e fornire matterUniqueId
come identificatore.
La risposta SYNC di esempio mostra l'utilizzo di questi campi:
{
"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",
}
]
}
]
}
}
Per saperne di più, consulta la
documentazione di Cloud-to-cloud SYNC
.
Metadati di dispositivo e tratto
I dispositivi e le caratteristiche nelle API Home hanno metadati associati, che possono aiutarti a gestire l'esperienza utente in un'app.
Ogni tratto nelle API Home contiene una proprietà
sourceConnectivity
, che contiene informazioni sullo stato online e sulla località di un tratto
(routing locale o remoto).
Recuperare il tipo principale di un dispositivo
Alcuni dispositivi potrebbero presentare più tipi di dispositivi tramite le API Home. Per assicurarti che gli utenti visualizzino le opzioni appropriate in un'app (come il controllo dei dispositivi e le automazioni suggerite) per i loro dispositivi, è utile verificare se un tipo di dispositivo è il tipo principale del 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.") } }
Controllare se un tratto è online
Leggi la proprietà connectivityState
per controllare la connettività di una caratteristica:
let levelControlConnectivity = levelControlTrait.metadata.sourceConnectivity .connectivityState
Alcune caratteristiche, in genere quelle di Google smart home, potrebbero essere visualizzate offline se il dispositivo non è connesso a internet. Questo perché queste caratteristiche sono basate sul cloud e non hanno routing locale.
Controllare la connettività di un dispositivo
La connettività di un dispositivo viene effettivamente controllata a livello di tipo di dispositivo perché alcuni dispositivi supportano più tipi di dispositivi. Lo stato restituito è una combinazione degli stati di connettività per tutte le caratteristiche del dispositivo.
let lightConnectivity = dimmableLightDeviceType.metadata.sourceConnectivity .connectivityState
Uno stato di partiallyOnline
può essere osservato nel caso di tipi di dispositivi misti
quando non è presente una connettività a internet. Matter standard
potrebbero essere ancora online a causa del routing locale, ma le caratteristiche basate sul cloud saranno
offline.
Controllare il routing di rete di un tratto
La località di una caratteristica è disponibile anche nelle API per la casa. dataSourceLocality
indica se la caratteristica viene instradata in remoto (tramite il cloud), localmente (tramite un hub locale) o peer-to-peer (direttamente da dispositivo a dispositivo, senza hub).
Il valore di località sconosciuto unspecified
è possibile, ad esempio, mentre un'app
si avvia e non ha ancora raggiunto un hub o un server per la connettività
del dispositivo. Questi dispositivi non sono raggiungibili e le richieste di interazione
da comandi o eventi non andranno a buon fine. Spetta al cliente determinare come
gestire questi dispositivi.
let levelControlLocality = levelControlTrait.metadata.sourceConnectivity .dataSourceLocality
Controllare il routing di rete per un dispositivo
Come la connettività, la località viene controllata a livello di tipo di dispositivo. Lo stato restituito è una combinazione della località per tutte le caratteristiche del dispositivo.
let lightLocality = dimmableLightDeviceType.metadata.sourceConnectivity.dataSourceLocality
In uno scenario simile a quello della connettività partiallyOnline
, potrebbe essere osservato uno stato di mixed
: alcuni tratti sono basati sul cloud, mentre altri sono locali.
Modificare il nome di un dispositivo
Chiama il metodo
setName(_:)
per modificare il nome di un dispositivo:
let updatedDevice = try await theDevice.setName("new device name")
Quando si modifica il nome di un dispositivo, la struttura HomeDevice
originale rimane
invariata e la modifica viene riflessa nell'oggetto HomeDevice
aggiornato restituito.
I nomi verranno troncati se superano il limite di 60 punti di codice Unicode (caratteri) e non verranno generati errori. Gli sviluppatori sono responsabili della gestione dei nomi lunghi e, ad esempio, possono decidere se informare gli utenti che i nomi verranno troncati.
elenco delle API
Una volta creata un'istanza di
Home
, sono accessibili tramite questa le
seguenti API Device:
API | Descrizione |
---|---|
device(id:) |
Restituisce un Publisher per il dispositivo specificato che emette lo stato del dispositivo ogni volta che cambia. |
devices() |
Recupera tutti i dispositivi in tutte le strutture dell'Account Google. Restituisce un Query<HomeDevice> che fornisce ulteriori opzioni di recupero e filtro. |
Una volta ottenuto un
HomeDevice
, le seguenti
API sono accessibili tramite questo:
API | Descrizione |
---|---|
id |
L'ID sistema univoco del dispositivo. |
name |
Il nome del dispositivo fornito dall'utente. |
structureID |
L'ID della struttura a cui è assegnato il dispositivo. Restituisce un valore String? . |
roomID |
L'ID della stanza a cui è assegnato il dispositivo. Restituisce un valore String? . |
types |
Ottieni un tipo specifico o tutti i tipi disponibili sul dispositivo. |
isMatterDevice |
Se il dispositivo è coperto da Matter. |
sourceConnectivity |
La connettività di origine del dispositivo, che rappresenta gli stati di connettività aggregati e la località di rete delle caratteristiche del dispositivo. |