裝置 API 可透過 Android 版 Google Home API 存取。 將下列套件匯入應用程式:
import com.google.home.Home
import com.google.home.HomeDevice
import com.google.home.Id
如要搭配使用特定裝置類型或特徵與 Device API,必須個別匯入。
舉例來說,如要使用「開/關」Matter特徵和「開/關外掛程式單元」裝置類型,請將下列套件匯入應用程式:
import com.google.home.matter.standard.OnOff
import com.google.home.matter.standard.OnOffPluginUnitDevice
詳情請參閱「Android 上的資料模型」。
處理錯誤
Home API 中的任何方法都可能擲回 HomeException
,因此建議您使用 try-catch
區塊,在所有呼叫中擷取 HomeException
。
處理 HomeException
時,請檢查 code
和 message
欄位,瞭解發生錯誤的原因。
任何未處理的例外狀況都會導致應用程式當機。
詳情請參閱「錯誤處理」一節。
如需範例,請參閱「將指令傳送至裝置」。
呼叫範例
取得裝置清單
有了可用結構,devices()
呼叫就會傳回您可從該結構存取的裝置 Flow:
// 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()
您可以在該處存取每個裝置的狀態,並將支援的指令傳送至裝置。
讀取裝置狀態
讓我們以檢查裝置的 OnOff
屬性為例,瞭解如何使用 On/Off 特徵。使用 Home API 特徵資料模型 (此特徵識別為 OnOff
),即可透過裝置類型的 standardTraits
類別擷取特徵資料:
// 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()!!
詳情請參閱 distinctUntilChanged
,進一步瞭解 Kotlin Flow 函式。
使特徵訂閱中的狀態失效
TraitStateInvalidation
介面可讓您在狀態回報不正確時,使透過訂閱項目擷取的目標裝置狀態失效。舉例來說,如果是在「C」品質的 Matter 特徵中使用屬性,或是裝置實作方式導致問題,狀態可能就無法正確回報。
這個 API 會強制讀取目前的特徵狀態,並透過現有的特徵流程傳回結果。
取得特徵,然後在特徵上執行 forceRead
:
val generalDiagnosticsTrait = device.trait(GeneralDiagnostics).first()
generalDiagnosticsTrait.forceRead()
取得裝置類型特徵清單
裝置類型應做為讀取特徵的進入點,因為這類類型會將裝置分解為功能片段 (例如 Matter 中的端點)。
如果裝置有兩種裝置類型,且兩者可能具有相同特徵,系統也會將特徵衝突納入考量。舉例來說,如果裝置同時是音箱和可調光燈具,就會有兩項開/關和兩項等級控制特徵。
如要取得可調光燈具裝置類型可用的特徵清單,請按照下列步驟操作:
// 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()
如果裝置有兩個名稱相同的特徵,也可能發生特徵衝突。舉例來說,onOff
可以參照標準 OnOff
特徵的例項,也可以參照製造商定義的 OnOff
特徵例項。為避免對預期特徵產生任何潛在的模糊不清,透過裝置參照的 Trait
執行個體應以限定命名空間為前置。如果是標準特徵 (即與 Matter 標準叢集類似的特徵),請使用 standardTraits
。如要使用 Google 特徵,請使用 googleTraits
:
// Accessing standard traits on the type. val onOffTrait: OnOff? = dimmableLightDevice.standardTraits.onOff val levelControlTrait: LevelControl? = dimmableLightDevice.standardTraits.levelControl
如要存取製造商專屬特徵,請直接參照該特徵:
// Accessing a custom trait on the type. val customTrait = dimmableLightDevice.trait(MyCustomTrait)
取得具有特定特徵的裝置清單
Kotlin 中的 filter
函式可用於進一步調整 API 呼叫。舉例來說,如要取得家中所有具備「開/關」特徵的裝置清單:
// Get all devices that support OnOff val onOffDevices: Flow<List<HomeDevice>> = home.devices().map { devices -> devices.filter { it.has(OnOff) } }
如要查看 Home API 提供的完整特徵清單,請參閱 Trait
介面。
取得裝置類型相似的裝置清單
如要取得代表住家所有燈具的裝置清單,請按照下列步驟操作:
// 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) } }
Home API 中有多種裝置類型,可代表核心裝置類型。舉例來說,沒有「燈具」裝置類型。如上例所示,有四種不同的裝置類型可以代表燈具。因此,如要全面瞭解住家中的高階裝置類型,篩選後的流程必須包含多種裝置類型。
如需 Home API 提供的裝置類型完整清單,請參閱 DeviceType
介面。
取得裝置的供應商 ID 或產品 ID
BasicInformation
特徵包含裝置的供應商 ID、產品 ID、產品名稱和序號等資訊:
// 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}")
裝置製造商的雲端對雲端裝置識別
如果您是裝置製造商,且建構 Cloud-to-cloud 裝置,如要透過 BasicInformation
特徵識別 Cloud-to-cloud 裝置,可以在 SYNC
回應中加入下列字串欄位:
Connectivity Standards Alliance (CSA) 已核發供應商 ID:
"matterOriginalVendorId": "0xfff1",
可專屬識別供應商產品的產品 ID:
"matterOriginalProductId": "0x1234",
裝置的專屬 ID,以製造商專屬方式建構:
"matterUniqueId": "matter-device-id",
輸入這些字串欄位時,請使用供應商和產品 ID (如有)。Matter如果不是 CSA 成員,且未獲派這些 ID,請將 matterOriginalVendorId
和 matterOriginalProductId
欄位留空,並提供 matterUniqueId
做為 ID。
範例 SYNC 回應會顯示這些欄位的使用情形:
{
"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",
}
]
}
]
}
}
詳情請參閱Cloud-to-cloud SYNC
說明文件。
裝置和特徵中繼資料
Google Home API 中的裝置和特徵會與中繼資料建立關聯,有助於管理應用程式中的使用者體驗。
Home API 中的每個特徵都包含 sourceConnectivity
屬性,其中含有特徵的線上狀態和位置資訊 (本機或遠端路徑)。
取得裝置的主要類型
部分裝置可能會透過 Home API 呈現多種裝置類型。 為確保使用者在應用程式中看到裝置的適當選項 (例如裝置控制和建議的自動化動作),建議檢查裝置的主要裝置類型。
首先,請使用 type()
取得裝置類型,然後判斷主要類型:
val types = device.types().first() val primaryTypes = types.filter { it.metadata.isPrimaryType }
檢查特徵是否處於線上狀態
使用 connectivityState()
方法檢查特徵的連線狀態:
val onOffConnectivity = onOffTrait?.metadata?.sourceConnectivity?.connectivityState
如果裝置未連上網際網路,部分特徵 (通常是 Google smart home 特徵) 可能會顯示為離線。這是因為這些特徵是以雲端為基礎,沒有本機路徑。
檢查裝置的連線狀態
裝置的連線狀態實際上是在裝置類型層級檢查,因為部分裝置支援多種裝置類型。傳回的狀態是該裝置上所有特徵的連線狀態組合。
val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState
如果沒有網際網路連線,混合裝置類型可能會出現 PARTIALLY_ONLINE
狀態。Matter 標準特徵碼可能仍會因本機路由而處於連線狀態,但雲端特徵碼會離線。
檢查特徵的網路路徑
特徵的地域性也可在 Home API 中使用。dataSourceLocality
表示特徵是透過遠端 (雲端)、本機 (本機中樞) 或對等互連 (直接從裝置到裝置,不透過中樞) 傳送。
舉例來說,應用程式啟動時可能還未連上中樞或伺服器,因此會出現不明區域值 UNSPECIFIED
。這些裝置無法連線,因此會導致指令或事件的互動要求失敗。如何處理這類裝置,則由用戶端決定。
val onOffLocality = onOffTrait?.metadata?.sourceConnectivity?.dataSourceLocality
檢查裝置的網路路徑
與連線能力一樣,區域性是在裝置類型層級檢查。傳回的狀態是該裝置上所有特徵的地區性組合。
val lightLocality = dimmableLightDevice.metadata.sourceConnectivity.dataSourceLocality
在類似的案例中,您可能會觀察到 MIXED
狀態,如同 PARTIALLY_ONLINE
連線狀態:某些特徵是雲端特徵,其他則是本機特徵。
變更裝置名稱
呼叫 setName()
方法來變更裝置名稱:
mixerDevice.setName("Grendel")
如果名稱超過 60 個 Unicode 碼點 (字元) 的限制,系統會截斷名稱,且不會擲回錯誤。開發人員有責任處理長名稱,例如決定是否要通知使用者名稱會遭到截斷。
API 清單
建立 Home
執行個體後,即可透過該執行個體存取下列裝置 API:
API | 說明 |
---|---|
devices() |
取得 Google 帳戶中所有結構的所有裝置。傳回 HomeObjectsFlow ,提供進一步的擷取和篩選選項。 |
取得 HomeDevice
後,即可透過該物件存取下列 API:
API | 說明 |
---|---|
allCandidates() |
傳回裝置及其子項的所有自動化候選項目。 |
candidates() |
傳回裝置的所有自動化候選項目。 |
connectivityStateChanged |
裝置狀態最近一次變更的時間。 |
events(event) |
取得特定事件的流程。 |
events(trait) |
取得此特徵的所有事件流程。 |
events(traits) |
取得這些特徵的所有事件流程。 |
getSourceConnectivity(trait) |
取得特定特徵的中繼資料。傳回 SourceConnectivity 。 |
has(trait) |
確認裝置是否支援目前要求使用的特徵。 |
has(type) |
如果裝置支援所提供的類型。 |
id |
裝置的專屬系統 ID。 |
isInRoom |
裝置是否位於房間。 |
isInStructure |
裝置是否位於結構中。 |
isMatterDevice |
如果裝置有 Matter 支援。 |
name |
使用者提供的裝置名稱。 |
room() |
裝置所屬的房間。傳回 Room 。 |
roomId |
裝置所屬房間的 ID。傳回 Id 。 |
sourceConnectivity |
裝置的來源連線,代表裝置特徵的匯總連線狀態和網路位置。 |
structure() |
裝置所指派的結構。傳回 Structure 。 |
structureId |
裝置所屬的結構體 ID。傳回 Id 。 |
type(type) |
取得填入特徵的型別定義 (如有),以便直接存取。一律傳回特徵的最新快照。 |
types() |
取得裝置上所有可用類型的清單。 |