Управление устройствами на iOS

Данное руководство является продолжением руководства «Доступ к устройствам и метаданным устройств в 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 Toggle, которая определена в модели данных экосистемы Google Home как toggle() . Этот метод изменяет onOff на false , если оно true , или на true если оно false :

// Calling a command on a trait.
do {
  try await onOffTraitTest.toggle()
} catch let _ as HomeError {
  // Code for handling the exception
}

Команды могут возвращать исключение, если обнаружена проблема в потоке выполнения. Как разработчик, вы должны использовать блок do-catch для надлежащей обработки таких исключений и предоставления пользователям подробной информации о случаях, когда ошибки требуют принятия мер. Необработанные исключения остановят выполнение приложения и могут привести к сбоям в его работе.

В качестве альтернативы, для явной установки состояния можно использовать команды off() или on() :

do {
  try await onOffTraitTest.off()
  try await onOffTraitTest.on()
} catch let _ as HomeError {
  // Code for handling the exception
}

После отправки команды на изменение состояния, по завершении процесса вы можете прочитать состояние, как описано в разделе «Чтение состояния устройства» , чтобы обработать его в своем приложении.

Отправьте команду с параметрами.

Некоторые команды могут использовать параметры, например, параметры функций OnOffTrait или LevelControlTrait :

offWithEffect

// Turn off the light using the DyingLight effect.
do {
  try await onOffTraitTest.offWithEffect(
    effectIdentifier: Matter.OnOffTrait.EffectIdentifierEnum.dyingLight,
    effectVariant: 0
  )
} catch let _ as HomeError {
  // Code for handling the exception
}

moveToLevel

// 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 _ as HomeError {
  // Code for handling the exception
}

Проверьте, поддерживает ли признак какой-либо атрибут.

Некоторые устройства могут поддерживать свойство Matter , но не конкретный атрибут. Например, устройство, Cloud-to-cloud сопоставленное с Matter , может не поддерживать все атрибуты Matter . Для обработки подобных случаев используйте свойство isSupported на уровне свойства, чтобы проверить, поддерживается ли атрибут для конкретного устройства.

Например, чтобы проверить, поддерживает ли устройство атрибут onOff свойства On/Off:

// 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 или схеме smart home Cloud-to-cloud некоторые атрибуты допускают значение nil. Для таких атрибутов можно определить, связано ли возвращаемое значение nil с тем, что устройство не сообщает это значение, или же значение атрибута действительно равно nil , используя isNullable в дополнение к isSupported :

// 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 \(String(describing: onOffTrait.attributes.startUpOnOff))"
      )
    }
  }
}

Обновить атрибуты признаков

Если вы хотите изменить значение определенного атрибута, и ни одна из команд этого свойства не позволяет это сделать, возможно, атрибут поддерживает явное указание своего значения.

Возможность изменения значения атрибута зависит от двух факторов:

  • Доступен ли данный атрибут для записи?
  • Может ли значение атрибута измениться в результате отправки команды для изменения свойства?

Эта информация содержится в справочной документации по признакам и их атрибутам.

Таким образом, комбинации свойств, определяющие способ изменения значения атрибута, следующие:

  • Атрибут доступен только для чтения и не затрагивается другими командами. Это означает, что его значение не изменяется. Например, значение атрибута currentPosition объекта SwitchTrait .

  • Атрибут доступен только для чтения и может изменяться под воздействием других команд. Это означает, что изменить значение атрибута можно только в результате отправки команды. Например, атрибут currentLevel объекта LevelControlTrait доступен только для чтения, но его значение может изменяться такими командами, как moveToLevel .

  • Атрибут доступен для записи и не подвержен влиянию других команд. Это означает, что вы можете напрямую изменить значение атрибута, используя функцию update трейта, но нет команд, которые могли бы повлиять на значение атрибута. Например, атрибут WrongCodeEntryLimit трейта DoorLockTrait .

  • Атрибут доступен для записи и может изменяться под воздействием других команд. Это означает, что вы можете напрямую изменять значение атрибута, используя функцию update трейта, а значение атрибута может изменяться в результате отправки команды. Например, в атрибут occupiedCoolingSetpoint трейта ThermostatTrait можно записывать данные, а также обновлять его с помощью команды setpointRaiseLower .

Пример использования функции обновления для изменения значения атрибута.

В этом примере показано, как явно задать значение атрибута DoorLockTrait.wrongCodeEntryLimit .

Чтобы установить значение атрибута, вызовите функцию update трейта и передайте ей функцию обновления, которая устанавливает новое значение. Рекомендуется сначала убедиться, что трейт поддерживает атрибут .

Например:

if doorLockTraitTest.attributes.$wrongCodeEntryLimit.isSupported {
  let _ = try await doorLockTraitTest.update {
    $0.setWrongCodeEntryLimit(3)
  }
}