Sterowanie urządzeniami w iOS

W tym przewodniku znajdziesz kontynuację sekcji Dostęp do urządzeń i metadanych urządzeń w systemie iOS oraz dodatkowe przykłady sterowania urządzeniami i uzyskiwania do nich dostępu.

Aby używać określonych typów lub cech urządzeń, takich jak Matter OnOffTrait użyte w wielu przykładach, musisz je zaimportować:

import GoogleHomeSDK
import GoogleHomeTypes

Sprawdź, czy cecha obsługuje polecenie

Użyj funkcji supports na poziomie cechy, aby sprawdzić, czy polecenie jest obsługiwane na danym urządzeniu.

Aby na przykład sprawdzić, czy urządzenie obsługuje polecenie toggle cechy Włączanie/wyłączanie:

// 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")
}

Wysyłanie polecenia do urządzenia

Wysłanie polecenia jest podobne do odczytania atrybutu stanu z cechy. Aby włączyć lub wyłączyć urządzenie, użyj polecenia przełączania OnOffTrait, które w modelu danych ekosystemu Google Home jest zdefiniowane jako toggle(). Ta metoda zmienia wartość onOff na false, jeśli jest ona równa true, lub na true, jeśli jest równa false:

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

Polecenia mogą zwracać wyjątek, jeśli w przepływie wykonania zostanie wykryty problem. Jako deweloper powinieneś używać bloku do-catch, aby prawidłowo obsługiwać te wyjątki i wyświetlać użytkownikom szczegółowe informacje w przypadkach, w których błędy wymagają podjęcia działań. Nieobsłużone wyjątki zatrzymają działanie aplikacji i mogą spowodować jej awarię.

Możesz też użyć poleceń off() lub on(), aby jednoznacznie ustawić stan:

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

Po wysłaniu polecenia zmiany stanu możesz po jego zakończeniu odczytać stan, jak opisano w sekcji Odczytywanie stanu urządzenia, aby obsłużyć go w swojej aplikacji.

Wysyłanie polecenia z parametrami

Niektóre polecenia mogą używać parametrów, np. te na OnOffTrait lub 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
}

Sprawdzanie, czy cecha obsługuje atrybut

Niektóre urządzenia mogą obsługiwać cechę Matter, ale nie konkretny atrybut. Na przykład urządzenie Cloud-to-cloud, które zostało przypisane do Matter, może nie obsługiwać wszystkich atrybutów Matter. Aby obsługiwać takie przypadki, użyj właściwości isSupported na poziomie cechy, aby sprawdzić, czy atrybut jest obsługiwany na danym urządzeniu.

Aby na przykład sprawdzić, czy urządzenie obsługuje atrybut onOff cechy Włączanie/wyłączanie:

// 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!")
}

Niektóre atrybuty mogą mieć wartość null w specyfikacji Matter lub w schemacie Cloud-to-cloud smart home. W przypadku tych atrybutów możesz określić, czy wartość null zwrócona przez atrybut jest spowodowana tym, że urządzenie nie zgłasza tej wartości, czy wartość atrybutu to w rzeczywistości nil. Aby to zrobić, użyj isNullable oprócz 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))"
      )
    }
  }
}

Zaktualizuj atrybuty cech

Jeśli chcesz zmienić wartość danego atrybutu, a żadne z poleceń tej cechy tego nie robi, atrybut może obsługiwać jawne ustawienie swojej wartości.

Możliwość zmiany wartości atrybutu zależy od 2 czynników:

  • Czy atrybut można zapisywać?
  • Czy wartość atrybutu może ulec zmianie jako efekt uboczny wysłania polecenia cechy?

Informacje te znajdziesz w dokumentacji referencyjnej dotyczącej cech i ich atrybutów.

Kombinacje właściwości, które określają, jak wartość atrybutu może zostać zmieniona, to:

  • Tylko do odczytu i nie ma na niego wpływu inne polecenia. Oznacza to, że wartość atrybutu się nie zmienia. Na przykład atrybut currentPosition elementu SwitchTrait.

  • Tylko do odczytu i podatne na inne polecenia. Oznacza to, że wartość atrybutu może ulec zmianie tylko w wyniku wysłania polecenia. Na przykład atrybut currentLevel elementu LevelControlTrait jest tylko do odczytu, ale jego wartość można zmieniać za pomocą poleceń takich jak moveToLevel.

  • Można je zapisywać i nie mają na nie wpływu inne polecenia. Oznacza to, że możesz bezpośrednio zmienić wartość atrybutu, korzystając z funkcji update cechy, ale nie ma poleceń, które miałyby wpływ na wartość atrybutu. Na przykład atrybut WrongCodeEntryLimit elementu DoorLockTrait.

  • Można w nich zapisywać dane i mają na nie wpływ inne polecenia. Oznacza to, że możesz bezpośrednio zmienić wartość atrybutu za pomocą funkcji update cechy, a wartość atrybutu może się zmienić w wyniku wysłania polecenia. Na przykład atrybut occupiedCoolingSetpoint tagu ThermostatTrait można zapisać, ale też zaktualizować za pomocą setpointRaiseLower polecenia.

Przykład użycia funkcji aktualizacji do zmiany wartości atrybutu

Ten przykład pokazuje, jak jawnie ustawić wartość DoorLockTrait.wrongCodeEntryLimit atrybutu.

Aby ustawić wartość atrybutu, wywołaj funkcję update cechy i przekaż jej funkcję aktualizacji, która ustawia nową wartość. Dobrą praktyką jest najpierw sprawdzenie, czy cecha obsługuje atrybut.

Na przykład:

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