È possibile accedere alle API del dispositivo tramite le API Home per Android. Importa questi pacchetti nella tua app:
import com.google.home.Home
import com.google.home.HomeDevice
import com.google.home.Id
Per utilizzare tipi o caratteristiche di dispositivi specifici con le API Device, questi devono essere importati singolarmente.
Ad esempio, per utilizzare il tratto Matter On/Off e il tipo di dispositivo Unità plug-in On/Off, importa i seguenti pacchetti nella tua applicazione:
import com.google.home.matter.standard.OnOff
import com.google.home.matter.standard.OnOffPluginUnitDevice
Per maggiori informazioni, vedi Modello dei dati su Android.
Gestione degli errori
Qualsiasi metodo nelle API Home può generare un'eccezione HomeException
, pertanto ti consigliamo di utilizzare un blocco try-catch
per rilevare HomeException
in tutte le chiamate.
Quando gestisci HomeException
, controlla i campi code
e message
per scoprire cosa è andato storto.
Qualsiasi eccezione non gestita causerà l'arresto anomalo dell'app.
Per saperne di più, consulta la sezione Gestione degli errori.
Per un esempio, vedi Inviare un comando a un dispositivo.
Chiamate di esempio
Recuperare un elenco di dispositivi
Con la struttura disponibile, una chiamata devices()
restituisce un flusso di dispositivi
accessibili dalla struttura:
// Get a flow of all devices accessible to the user val allDevicesFlow: HomeObjectsFlow<HomeDevice> = home.devices() // Calling list() on a HomeObjectsFlow returns the first Set of elements. val allDevices: Set<HomeDevice> = allDevicesFlow.list()
Da qui, sono accessibili gli stati di ogni dispositivo e possono essere inviati al dispositivo i comandi supportati.
Leggere lo stato di un dispositivo
Vediamo un esempio di controllo dell'attributo OnOff
dalla caratteristica On/Off del dispositivo. Utilizzando il modello di dati del tratto delle API Home, in cui questo tratto è
identificato come OnOff
, puoi recuperare i dati del tratto tramite la classe
standardTraits
del tipo di dispositivo:
// Assuming we have a device. val deviceFlow = home.devices().itemFlow(myDeviceId) val device = deviceFlow.first() // Get a flow of a standard trait on the type. distinctUntilChanged() is needed to only trigger // on the specific trait changes and not the whole type. val onOffTraitFlow: Flow<OnOff?> = device.type(DimmableLightDevice).map { it.standardTraits.onOff }.distinctUntilChanged() val onOffTrait: OnOff = onOffTraitFlow.first()!!
Consulta
distinctUntilChanged
per scoprire di più sulla funzione di flusso Kotlin.
Invalidare lo stato in un abbonamento al tratto
L'interfaccia TraitStateInvalidation
consente di invalidare uno stato recuperato tramite abbonamenti
al dispositivo di destinazione nei casi in cui lo stato non viene segnalato correttamente.
Esempi di casi in cui lo stato potrebbe non essere segnalato correttamente includono
l'utilizzo di attributi in caratteristiche Matter con qualità "C"
o a causa di un'implementazione del dispositivo che causa inaspettatamente il problema.
Questa API esegue una lettura forzata dello stato attuale del tratto e restituisce il risultato tramite i flussi dei tratti esistenti.
Ottieni il tratto, quindi esegui un forceRead
sul tratto:
val generalDiagnosticsTrait = device.trait(GeneralDiagnostics).first()
generalDiagnosticsTrait.forceRead()
Recuperare un elenco di caratteristiche del tipo di dispositivo
I tipi di dispositivo devono essere utilizzati come punto di partenza 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 di controllo di accensione/spegnimento e due di controllo del livello.
Per ottenere l'elenco delle caratteristiche disponibili per il tipo di dispositivo Luce dimmerabile:
// Get all types available on this device. Requires the types to be part of the registry during // SDK initialization. val typesFlow: Flow<Set<DeviceType>> = device.types() // Get a snapshot of all types. val types: Set<DeviceType> = typesFlow.first() // Get the DimmableLightDevice instance from the set of types. val dimmableLightDevice = types.filterIsInstance<DimmableLightDevice>().firstOrNull() // Get all traits in the type + traits registered val allTraits: Set<Trait> = dimmableLightDevice!!.traits()
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
inteso, un'istanza Trait
a cui viene fatto riferimento tramite un dispositivo deve essere preceduta da
uno spazio dei nomi qualificante. Per i tratti standard, ovvero quelli analoghi ai cluster standard Matter, utilizza standardTraits
. Per i tratti
di Google, utilizza googleTraits
:
// Accessing standard traits on the type. val onOffTrait: OnOff? = dimmableLightDevice.standardTraits.onOff val levelControlTrait: LevelControl? = dimmableLightDevice.standardTraits.levelControl
Per accedere a una caratteristica specifica del produttore, fai riferimento direttamente a quest'ultima:
// Accessing a custom trait on the type. val customTrait = dimmableLightDevice.trait(MyCustomTrait)
Visualizzare un elenco di dispositivi con una caratteristica specifica
La funzione
filter
in Kotlin può essere utilizzata per perfezionare ulteriormente le chiamate API. Ad esempio, per ottenere un elenco dei dispositivi della casa che hanno tutti la caratteristica On/Off:
// Get all devices that support OnOff val onOffDevices: Flow<List<HomeDevice>> = home.devices().map { devices -> devices.filter { it.has(OnOff) } }
Consulta l'interfaccia Trait
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) val lightDevices = home.devices().map { devices -> devices.filter { it.has(DimmableLightDevice) || it.has(OnOffLightDevice) || it.has(ColorTemperatureLightDevice) || it.has(ExtendedColorLightDevice) } }
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, è necessario includere più tipi di dispositivi nei flussi filtrati.
Consulta l'interfaccia DeviceType
per un elenco completo dei tipi di dispositivi disponibili nelle API Home.
Recuperare l'ID fornitore o l'ID prodotto per un dispositivo
Il tratto BasicInformation
include informazioni quali ID fornitore, ID prodotto, nome prodotto e
numero di serie di un dispositivo:
// Get device basic information. All general information traits are on the RootNodeDevice type. val basicInformation = device.type(RootNodeDevice).first().standardTraits.basicInformation!! println("vendorName ${basicInformation.vendorName}") println("vendorId ${basicInformation.vendorId}") println("productId ${basicInformation.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 assicurarsi che gli utenti visualizzino le opzioni appropriate in un'app (come il controllo dei dispositivi e le automazioni suggerite) per i loro dispositivi, è utile controllare il tipo di dispositivo principale per un dispositivo.
Innanzitutto, recupera i tipi di dispositivo utilizzando
type()
,
quindi determina i tipi principali:
val types = device.types().first() val primaryTypes = types.filter { it.metadata.isPrimaryType }
Controllare se un tratto è online
Utilizza il metodo connectivityState()
per controllare la connettività di un tratto:
val onOffConnectivity = onOffTrait?.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.
val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState
In caso di tipi di dispositivi misti, quando non è presente una connettività a internet, potrebbe essere osservato uno stato di PARTIALLY_ONLINE
.
Le caratteristiche standard di Matter 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. Il
dataSourceLocality
indica se la caratteristica viene instradata da remoto (tramite
il cloud), localmente (tramite un hub locale) o peer-to-peer (direttamente dal dispositivo
al dispositivo, senza hub).
Il valore di località sconosciuta UNSPECIFIED
è possibile, ad esempio, mentre un'app
è in fase di avvio 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.
val onOffLocality = onOffTrait?.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.
val lightLocality = dimmableLightDevice.metadata.sourceConnectivity.dataSourceLocality
In uno scenario simile, potrebbe essere osservato uno stato di MIXED
come quello della connettività di PARTIALLY_ONLINE
: alcune caratteristiche sono basate sul cloud, mentre altre sono locali.
Modificare il nome di un dispositivo
Chiama il metodo setName()
per modificare il nome di un dispositivo:
mixerDevice.setName("Grendel")
elenco delle API
Una volta creata un'istanza di
Home
, sono accessibili tramite questa le
seguenti API Device:
API | Descrizione |
---|---|
devices() |
Recupera tutti i dispositivi in tutte le strutture dell'Account Google. Restituisce un HomeObjectsFlow che fornisce ulteriori opzioni di recupero e filtro. |
Una volta ottenuto un HomeDevice
,
le seguenti API sono accessibili tramite questo token:
API | Descrizione |
---|---|
allCandidates() |
Restituisce tutti i candidati all'automazione per il dispositivo e i relativi dispositivi secondari. |
candidates() |
Restituisce tutti i candidati all'automazione per il dispositivo. |
connectivityStateChanged |
L'ultima volta che lo stato del dispositivo è cambiato. |
events(event) |
Recupera un flusso di un evento specifico. |
events(trait) |
Recupera un flusso di tutti gli eventi in base a questo tratto. |
events(traits) |
Recupera un flusso di tutti gli eventi in base a questi tratti. |
getSourceConnectivity(trait) |
Ottieni i metadati per un tratto specifico. Restituisce un valore SourceConnectivity . |
has(trait) |
Controlla se la caratteristica richiesta è supportata dal dispositivo. |
has(type) |
Se il dispositivo supporta il tipo fornito. |
id |
L'ID sistema univoco del dispositivo. |
isInRoom |
Se il dispositivo si trova in una stanza. |
isInStructure |
Se il dispositivo si trova in una struttura. |
isMatterDevice |
Se il dispositivo è coperto da Matter. |
name |
Il nome del dispositivo fornito dall'utente. |
room() |
La stanza a cui è assegnato il dispositivo. Restituisce un valore Room . |
roomId |
L'ID della stanza a cui è assegnato il dispositivo. Restituisce un Id . |
sourceConnectivity |
La connettività di origine del dispositivo, che rappresenta gli stati di connettività aggregati e la località di rete delle caratteristiche del dispositivo. |
structure() |
La struttura a cui è assegnato il dispositivo. Restituisce un valore Structure . |
structureId |
L'ID della struttura a cui è assegnato il dispositivo. Restituisce un Id . |
type(type) |
Ottieni la definizione del tipo con i tratti compilati (se disponibili) per l'accesso diretto. Restituisce sempre uno snapshot aggiornato dei tratti. |
types() |
Visualizza un elenco di tutti i tipi disponibili sul dispositivo. |