裝置 API 可透過 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
詳情請參閱「資料模型」。
處理錯誤
Home API 中的任何方法都可能擲回 HomeException
,因此建議您使用 try-catch
區塊,在所有呼叫中擷取 HomeException
。
處理 HomeException
時,請檢查其 code
和 message
欄位,瞭解錯誤所在。
任何未處理的例外狀況都會導致應用程式停止運作。
詳情請參閱「錯誤處理」。
如需範例,請參閱「向裝置傳送指令」。
呼叫範例
取得裝置清單
當結構體可用時,devices()
呼叫會傳回可透過該結構體存取的裝置流程:
// 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
屬性。使用 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 流程函式。
在特徵訂閱中使狀態失效
在狀態未正確回報的情況下,TraitStateInvalidation
介面可讓您將透過訂閱從目標裝置擷取的狀態設為無效。狀態可能無法正確回報的情況包括:在 Matter 特徵中使用「C」品質的屬性,或是由於裝置實作意外導致問題。
這個 API 會強制讀取目前特徵狀態,並透過現有特徵流程傳回結果。
取得特徵,然後對特徵執行 forceRead
:
val generalDiagnosticsTrait = device.trait(GeneralDiagnostics).first()
generalDiagnosticsTrait.forceRead()
取得裝置類型特徵清單
裝置類型應用於讀取特徵的進入點,因為它們會將裝置分解為功能性部分 (例如 Matter 中的端點)。
當裝置具有兩種裝置類型,且兩者都可能具有相同特徵時,這些特徵也會考量特徵衝突。舉例來說,如果裝置同時是喇叭和可調光燈,就會有兩個開/關和兩個 Level Control 特徵。
如要取得可調光燈具裝置類型的可用特徵清單,請按照下列步驟操作:
// 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:用於唯一識別供應商產品的 ID:
"matterOriginalProductId": "0x1234",
裝置的專屬 ID,以製造商專屬方式建構:
"matterUniqueId": "matter-device-id",
輸入這些字串欄位時,請使用您的 Matter 供應商和產品 ID (如有)。如果您不是 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
說明文件。
裝置和特徵中繼資料
Home API 中的裝置和特徵會附帶相關聯的結構描述,有助於管理應用程式中的使用者體驗。
Home API 中的每個特徵都包含 sourceConnectivity
屬性,其中包含特徵的線上狀態和位置資訊 (本機或遠端路由)。
取得裝置的主要類型
部分裝置可能會透過 Google Home API 呈現多種裝置類型。為了確保使用者在應用程式中看到適合其裝置的選項 (例如裝置控制和建議的自動化動作),建議您檢查裝置的主要裝置類型。
首先,請使用 type()
取得裝置類型,然後判斷哪個類型為主要類型:
val types = device.types().first() val primaryType = types.first { 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
在 PARTIALLY_ONLINE
連線類似的情況下,可能會觀察到 MIXED
狀態:部分特徵是雲端式,其他則是本機式。
API 清單
建立 Home
的例項後,即可透過該例項存取下列 Device API:
API | 說明 |
---|---|
devices() |
取得 Google 帳戶中所有結構體的所有裝置。傳回 HomeObjectsFlow ,提供進一步的擷取和篩選選項。 |
取得 HomeDevice
後,您可以透過該 API 存取下列 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() |
取得裝置上可用的所有類型清單。 |