Управление устройствами на 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 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 :

offWithEffect

// 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 , но не определенный атрибут. Например, устройство Cloud-to-cloud , сопоставленное с Matter , может не поддерживать каждый атрибут 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!")
}

Некоторые атрибуты допускают значение null в спецификации Matter или схеме smart home Cloud-to-cloud . Для этих атрибутов вы можете определить, является ли возвращаемое атрибутом значение 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 \(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)
  }
}