本指南是「在 iOS 上存取裝置和裝置中繼資料」的延伸,將介紹更多裝置控制和存取權的範例。
如要使用特定裝置類型或特徵 (例如這裡許多範例中使用的 Matter
OnOffTrait
),必須匯入這些類型或特徵:
import GoogleHomeSDK
import GoogleHomeTypes
檢查特徵是否支援指令
使用特徵層級 supports
函式,檢查特定裝置是否支援指令。
舉例來說,如要檢查裝置是否支援開/關特徵的 toggle
指令,請按照下列步驟操作:
// Check if the OnOff trait supports the toggle command. if onOffTraitTest.supportsToggleCommand { print("onOffTrait supports toggle command") } else { print("onOffTrait does not support stateful toggle command") }
將指令傳送至裝置
傳送指令的做法類似於從特徵讀取狀態屬性。如要開啟或關閉裝置,請使用 OnOffTrait
切換指令,在 Google Home 生態系統資料模型中,這項指令的定義為 toggle()
。如果 onOff
為 true
,這個方法會將其變更為 false
;如果 onOff
為 false
,則會變更為 true
:
// Calling a command on a trait. do { try await onOffTraitTest.toggle() } catch let error as HomeError { // Code for handling the exception }
如果執行流程中發生問題,指令可能會傳回例外狀況。開發人員應使用 do-catch
區塊妥善處理這些例外狀況,並在錯誤可採取行動的情況下,向使用者顯示詳細資訊。未處理的例外狀況會停止應用程式執行階段,並可能導致應用程式當機。
或者,您也可以使用 off()
或 on()
指令明確設定狀態:
do { try await onOffTraitTest.off() try await onOffTraitTest.on() } catch let error as HomeError { // Code for handling the exception }
傳送指令變更狀態後,在指令完成後,您可以依照「讀取裝置狀態」一節的說明讀取狀態,在應用程式中加以處理。
傳送含有參數的指令
部分指令可能會使用參數,例如 OnOffTrait
或 LevelControlTrait
上的參數:
// Turn off the light using the DyingLight effect. do { try await onOffTraitTest.offWithEffect( effectIdentifier: Matter.OnOffTrait.EffectIdentifierEnum.dyingLight, effectVariant: 0 ) } catch let error as HomeError { // Code for handling the exception }
// Change the brightness of the light to 50% do { try await levelControlTraitTest.moveToLevel( level: UInt8(127), transitionTime: 0, optionsMask: Matter.LevelControlTrait.OptionsBitmap(), optionsOverride: Matter.LevelControlTrait.OptionsBitmap() ) } catch let error as HomeError { // Code for handling the exception }
檢查特徵是否支援屬性
部分裝置可能支援 Matter 特徵,但不支援特定屬性。舉例來說,已對應至 Matter 的 Cloud-to-cloud 裝置可能不支援所有 Matter 屬性。如要處理這類情況,請使用特徵層級 isSupported
屬性,檢查特定裝置是否支援該屬性。
舉例來說,如要檢查裝置是否支援開/關特徵的 onOff
屬性:
// Check if the OnOff trait supports the onOff attribute. if onOffTrait.attributes.$onOff.isSupported { print("onOffTrait supports onOff state") } else { print("onOffTrait is for a command only device!") }
在 Matter 規格或 Cloud-to-cloud smart home 架構中,部分屬性可為空值。針對這些屬性,您可以使用 isNullable
和 isSupported
,判斷屬性傳回的 nil 是因為裝置未回報該值,還是屬性值實際上是 nil
:
// Check if a nullable attribute is set or is not supported. if let deviceType = await device.types.get(OnOffLightDeviceType.self) { if let onOffTrait = deviceType.traits[Matter.OnOffTrait.self] { if onOffTrait.attributes.startUpOnOff == nil { if onOffTrait.attributes.$startUpOnOff.isSupported { print( "onOffTrait supports startUpOnOff and it is nil. Check the spec for the contextual meaning." ) } else { print("onOffTrait does not support startUpOnOff!") } } else { print( "onOffTrait supports startUpOnOff and it is set to \(onOffTrait.attributes.startUpOnOff)" ) } } }
更新特徵屬性
如果您想變更特定屬性的值,但特徵的命令都無法執行此操作,則該屬性可能支援明確設定值。
屬性的值是否可變更,取決於兩個因素:
- 屬性是否可寫入?
- 屬性值是否會因傳送特徵指令而產生副作用?
特徵及其屬性的參考說明文件會提供這項資訊。
因此,決定屬性值變更方式的屬性組合如下:
只讀,且不會受到其他指令影響。也就是說,屬性值不會變更。例如
SwitchTrait
的currentPosition
屬性。唯讀,且會受到其他指令影響。也就是說,只有在傳送指令時,屬性值才會變更。舉例來說,
LevelControlTrait
的currentLevel
屬性為唯讀,但其值可透過moveToLevel
等指令變更。可寫入,且不會受到其他指令影響。也就是說,您可以使用特徵的
update
函式直接變更屬性值,但沒有任何指令會影響屬性值。例如DoorLockTrait
的WrongCodeEntryLimit
屬性。可寫入,且會受到其他指令影響。也就是說,您可以使用特徵的
update
函式直接變更屬性值,而屬性值也會隨著傳送指令而變更。舉例來說,ThermostatTrait
的occupiedCoolingSetpoint
屬性可以寫入,但也可以透過setpointRaiseLower
指令進行更新。
使用更新函式變更屬性值的範例
這個範例說明如何明確設定 DoorLockTrait.wrongCodeEntryLimit
屬性的值。
如要設定屬性值,請呼叫特徵的 update
函式,並傳遞設定新值的更新函式。建議您先確認特徵是否支援屬性。
例如:
if doorLockTraitTest.attributes.$wrongCodeEntryLimit.isSupported { let _ = try await doorLockTraitTest.update { $0.setWrongCodeEntryLimit(3) } }