您可以透過 iOS 版 Home API 存取裝置 API。將下列套件匯入應用程式:
import GoogleHomeSDK
import GoogleHomeTypes
詳情請參閱「iOS 上的資料模型」。
處理錯誤
Home API 中的某些方法會擲回 HomeError
,因此建議您使用 do-catch
區塊,在這些呼叫中擷取 HomeError
。
處理 HomeError
時,請檢查其 code
和 message
欄位,瞭解錯誤所在。
任何未處理的錯誤都會導致應用程式當機。
詳情請參閱「錯誤處理」一文。
如需範例,請參閱「將指令傳送至裝置」。
呼叫範例
取得裝置清單
使用 Home
物件的參照,請叫用 devices()
取得可存取裝置的 Query
。呼叫 Query
的 batched()
方法,該方法會在每次裝置中繼資料變更時,發出反映住家目前狀態的 Set。或者,您也可以呼叫 Query.list()
取得可用裝置的快照。這是一個方便的方法,可訂閱 batched()
串流並傳回第一個發出的值。Query.stream()
會產生串流,在裝置名稱、房間或結構等中繼資料變更時發出新值。在內部,這個方法會使用 batched()
,並只傳送已變更的屬性。
// Get a list of all devices accessible to the user let homeDevices = try await self.home.devices().list()
您可以透過這裡存取每個裝置的狀態,並將支援的指令傳送至裝置。
取得裝置類型
如要取得與裝置相關聯的裝置類型,請讀取裝置的 types
屬性,該屬性會傳回 DeviceTypeController
。
呼叫 DeviceTypeController.subscribe(_:)
即可訂閱特定裝置類型的更新:
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") } }
如果裝置不支援指定的裝置類型,則會傳回立即完成的 Empty
Publisher
。
如果裝置支援特定的裝置類型,您可以呼叫 get()
取得該類型的句柄:
if let device = devices.first(where: { $0.id == myDeviceId }) { let deviceType = await device.types.get(OnOffLightDeviceType.self) }
如果裝置不支援指定的類型,則會傳回 nil
。
呼叫 DeviceTypeController.subscribeAll()
取得 DeviceTypeCollection
的 Publisher
。這個類別可讓您檢查裝置是否具有特定裝置類型:
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] } }
取得裝置類型特徵
裝置類型是讀取特徵的進入點,因為它們會將裝置分解為功能性部分 (例如 Matter 中的端點)。
當裝置具有兩種裝置類型,且兩者可能具有相同特徵時,這些特徵也會考量特徵衝突。舉例來說,如果裝置同時是喇叭和可調光燈具,就會有兩個開/關和兩個 Level Control 特徵。
如果裝置有兩個同名的特徵,就可能發生另一種特徵衝突。舉例來說,onOff
可以參照標準 OnOff
特徵的例項,也可以參照製造商定義的 OnOff
特徵例項。為避免產生任何關於特徵的模糊空間,請透過每個裝置類型的兩個特徵集合之一,參照特徵。
針對標準特徵 (即類似於 Matter 標準叢集的那些特徵),請使用 matterTraits
。舉例來說,如要取得可調光燈具裝置類型的特定特徵:
if let dimmableLightDeviceType = await device.types.get(DimmableLightDeviceType.self) { // Accessing standard trait on the type. let levelControlTrait = dimmableLightDeviceType.matterTraits.levelControlTrait.self }
如要使用 Google 特徵,請使用 googleTraits
:
if let doorbellDeviceType = await device.types.get(GoogleDoorbellDeviceType.self) { // Accessing Google trait on the type. let doorbellPressTrait = doorbellDeviceType.googleTraits.doorbellPressTrait.self }
如要存取特定製造商特徵,請透過 traits
屬性參照,但請在前面加上製造商的套件名稱:
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 }
讀取裝置狀態
請參考以下檢查裝置開/關特徵的 OnOff
屬性的範例:
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 }
取得具有特定特徵的裝置清單
如要取得具有特定特徵的裝置清單,您必須對裝置、每部裝置的裝置類型和每個裝置類型的特徵進行疊代。舉例來說,如要取得住家中所有具備開/關特徵的裝置清單,請執行下列操作:
// 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) } } }
如需 Home API 中可用的特徵完整清單,請參閱「iOS 特徵索引」。
取得類似裝置類型的裝置清單
如要取得代表住家所有燈具的裝置清單,請按照下列步驟操作:
// 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) }
Home API 中有多種裝置類型可代表核心裝置類型。例如,沒有「燈具」裝置類型。相反地,有四種不同的裝置類型可代表燈具,如上述範例所示。因此,如要全面掌握住家中較高層級的裝置類型,就必須納入多種裝置類型。
如需裝置類型和 Home API 中可用的特徵完整清單,請參閱「iOS 支援的裝置類型」。
取得裝置的供應商名稱、供應商 ID 或產品 ID
BasicInformationTrait
特徵包含供應商 ID、產品 ID、產品名稱和裝置序號等資訊:
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") }
找出雲端到雲端裝置
如果您是裝置製造商,並建構 Cloud-to-cloud 裝置,為了透過 BasicInformationTrait
識別您的 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 呈現多種裝置類型。為確保使用者在應用程式中看到適合其裝置的選項 (例如裝置控制和建議的自動化動作),建議您檢查裝置類型是否為裝置的主要類型。
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.") } }
檢查特徵是否已上線
如要檢查特徵的連線情形,請讀取 connectivityState
屬性:
let levelControlConnectivity = levelControlTrait.metadata.sourceConnectivity .connectivityState
如果裝置沒有網際網路連線,部分特徵 (通常是 Google smart home 特徵) 可能會顯示為離線。這是因為這些特徵是雲端型,且沒有本機路由。
檢查裝置的連線狀態
裝置的連線功能實際上是在裝置類型層級檢查,因為某些裝置支援多種裝置類型。傳回的狀態是該裝置上所有特徵的連線狀態組合。
let lightConnectivity = dimmableLightDeviceType.metadata.sourceConnectivity .connectivityState
在沒有網際網路連線的情況下,如果裝置類型混合,可能會觀察到 partiallyOnline
狀態。Matter 由於本地路由,標準特徵可能仍會上線,但雲端特徵會離線。
檢查特徵的網路路由
特徵的地區資訊也可在 Home API 中使用。dataSourceLocality
會指出特徵是透過雲端遠端路由、透過本機路由 (透過本機中樞) 或點對點 (直接從裝置傳送至裝置,不經過中樞) 傳送。
例如,當應用程式正在啟動,但尚未連上裝置連線的中心或伺服器時,就可能會出現不明的區域值 unspecified
。這些裝置無法連線,因此無法回應指令或事件的互動要求。客戶可以自行決定如何處理這類裝置。
let levelControlLocality = levelControlTrait.metadata.sourceConnectivity .dataSourceLocality
檢查裝置的網路路由
與連線性一樣,系統會在裝置類型層級檢查區域性。系統會傳回該裝置上所有特徵的區域組合。
let lightLocality = dimmableLightDeviceType.metadata.sourceConnectivity.dataSourceLocality
在 partiallyOnline
連線類似的情況下,可能會觀察到 mixed
的狀態:部分特徵是雲端式,其他則是本機式。
API 清單
建立 Home
的例項後,即可透過該例項存取下列 Device API:
API | 說明 |
---|---|
device(id:) |
針對指定裝置傳回 Publisher ,該裝置會在裝置狀態發生變更時發出。 |
devices() |
取得 Google 帳戶中所有結構體的所有裝置。傳回 Query<HomeDevice> ,提供進一步的擷取和篩選選項。 |
取得 HomeDevice
後,您可以透過該物件存取下列 API:
API | 說明 |
---|---|
id |
裝置的專屬系統 ID。 |
name |
使用者提供的裝置名稱。 |
structureID |
裝置所屬結構體的 ID。傳回 String? 。 |
roomID |
裝置指派到的房間 ID。傳回 String? 。 |
types |
取得裝置上的特定類型或所有可用類型。 |
isMatterDevice |
如果裝置由 Matter 備份。 |
sourceConnectivity |
裝置的來源連線,代表裝置特徵的匯總連線狀態和網路位置。 |