iOS'te cihazları kontrol etme

Bu kılavuz, iOS'te cihazlara ve cihaz meta verilerine erişme bölümünden devam eder ve cihaz kontrolü ile erişimiyle ilgili ek örnekler sunar.

Buradaki örneklerin çoğunda kullanılan Matter OnOffTrait gibi belirli cihaz türlerini veya özelliklerini kullanmak için bunların içe aktarılması gerekir:

import GoogleHomeSDK
import GoogleHomeTypes

Bir özelliğin bir komutu destekleyip desteklemediğini kontrol etme

Bir komutun belirli bir cihaz için desteklenip desteklenmediğini kontrol etmek amacıyla özellik düzeyindeki supports işlevini kullanın.

Örneğin, bir cihazın Açma/Kapatma özelliğinin toggle komutunu destekleyip desteklemediğini kontrol etmek için:

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

Cihaza komut gönderme

Komut gönderme, bir özellikten durum özelliği okumaya benzer. Cihazı açmak veya kapatmak için Google Home ekosistem veri modelinde toggle() olarak tanımlanan OnOffTrait Aç/Kapat komutunu kullanın. Bu yöntem, onOff değerini true ise false, false ise true olarak değiştirir:

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

Yürütme akışıyla ilgili bir sorun algılanırsa komutlar bir istisna döndürebilir. Geliştirici olarak, bu istisnaları düzgün bir şekilde ele almak için do-catch bloğu kullanmanız ve hataların düzeltilebileceği durumlarda kullanıcılara ayrıntılı bilgi vermeniz gerekir. İşlenmeyen istisnalar, uygulamanın çalışma zamanını durdurur ve uygulamanızda kilitlenmelere neden olabilir.

Alternatif olarak, durumu açıkça ayarlamak için off() veya on() komutlarını kullanın:

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

Durumu değiştirmek için bir komut gönderdikten sonra, komut tamamlandığında durumu Cihaz durumunu okuma bölümünde açıklandığı gibi okuyarak uygulamanızda işleyebilirsiniz.

Parametrelerle komut gönderme

Bazı komutlar, OnOffTrait veya LevelControlTrait sayfasındakiler gibi parametreler kullanabilir:

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
}

Bir özelliğin bir niteliği destekleyip desteklemediğini kontrol etme

Bazı cihazlar bir Matter özelliğini destekleyebilir ancak belirli bir özelliği desteklemeyebilir. Örneğin, Matter ile eşlenen bir Cloud-to-cloud cihazı, her Matter özelliğini desteklemeyebilir. Bu gibi durumları yönetmek için özellik düzeyindeki isSupported özelliğini kullanarak özelliğin belirli bir cihazda desteklenip desteklenmediğini kontrol edin.

Örneğin, bir cihazın Açma/Kapatma özelliğinin onOff özelliğini destekleyip desteklemediğini kontrol etmek için:

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

Bazı özellikler Matter spesifikasyonunda veya Cloud-to-cloud smart home şemasında null değer alabilir. Bu özellikler için, özelliğin döndürdüğü nil değerinin, cihazın bu değeri bildirmemesinden mi yoksa özelliğin değerinin gerçekten nil olmasından mı kaynaklandığını belirlemek için isSupported özelliğine ek olarak isNullable özelliğini kullanabilirsiniz:

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

Karakter özelliklerini güncelleme

Belirli bir özelliğin değerini değiştirmek istiyorsanız ve özelliğin komutlarından hiçbiri bunu yapmıyorsa özellik, değerinin açıkça ayarlanmasını destekleyebilir.

Bir özelliğin değerinin değiştirilip değiştirilemeyeceği iki faktöre bağlıdır:

  • Özellik yazılabilir mi?
  • Özellik komutu göndermenin yan etkisi olarak özelliğin değeri değişebilir mi?

Özellikler ve nitelikleriyle ilgili referans belgelerinde bu bilgiler yer alır.

Bu nedenle, bir özelliğin değerinin nasıl değiştirilebileceğini belirleyen özellik kombinasyonları şunlardır:

Bir özelliğin değerini değiştirmek için güncelleme işlevini kullanma örneği

Bu örnekte, DoorLockTrait.wrongCodeEntryLimit özelliğinin değerinin açıkça nasıl ayarlanacağı gösterilmektedir.

Bir özellik değeri ayarlamak için özelliğin update işlevini çağırın ve yeni değeri ayarlayan bir güncelleme işlevi iletin. Öncelikle özelliğin bir niteliği desteklediğini doğrulamanız önerilir.

Örneğin:

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

Cihaz grubunu kontrol etme

Üye cihazları arasında gezinerek bir grubun her üyesi üzerinde ayrıntılı kontrol sahibi olmanın yanı sıra DeviceGroup'yi tek bir varlık olarak kontrol edebilirsiniz. DeviceGroup, HasParts protokolüne uygundur ve gruptaki cihazlar tarafından desteklenen DeviceType parçalarını gösterir:

  • await group.part(_:), grup destekliyorsa belirtilen DeviceType öğesinin ilk örneğini, desteklemiyorsa nil değerini döndürür.
  • try await group.parts(_:), belirtilen DeviceType ile eşleşen tüm üst düzey parçaların bir dizisini döndürür.

Bir DeviceGroup kapsamındaki cihaz türünde özellik komutu çağırdığınızda SDK, temel bağlantı veya aktarım türünden (ör. Matter veya Cloud-to-cloud) bağımsız olarak komutu gruptaki bu özelliği destekleyen tüm ilişkili üye cihazlara iletir.

Grup parça özelliği nitelikleri ve hata işleme

Bir grup parçasını hedeflemek, bir grup genelinde idempotent komut (ışıkları açma veya kapatma ya da parlaklık seviyesi ayarlama gibi) göndermek istediğiniz yaygın durumları basitleştirir. DeviceGroup parçasında özellikler ve komutlarla çalışırken aşağıdaki davranışları göz önünde bulundurun:

  • Dinamik durum özellikleri (ör. OnOffTrait öğesinin onOff özelliği veya LevelControlTrait öğesinin currentLevel özelliği) genellikle bir grup parçasının özelliğinde doldurulmaz. Bunun nedeni, gruptaki üye cihazların tek bir değerde birleştirilemeyen farklı durumlarda olabilmesidir. Ancak desteklenen komutlar (supports(_:) ile kontrol edilir, örneğin kısılabilir bir ışıkta .moveToLevelWithOnOff) ve belirli özellik nitelikleri (örneğin, renkli ışıklar için ColorControlTrait üzerinde colorTempPhysicalMinMireds ve colorTempPhysicalMaxMireds) doldurulur. Böylece uygulamanız, kullanıcı arayüzü kontrollerini uygun şekilde yapılandırabilir.
  • Grup üyelerinin özellikleriyle ilgili tüm komutlar grup parçasında kullanılamaz. Özellikle değer döndüren komutlar kullanılamaz.
  • Grup bölümündeki bir komut, her bir temel üye cihaz komutu için ayrı sonuçlar döndürmez. Bağımsız komut sonuçlarını incelemek veya değer döndüren komutları çağırmak için doğrudan grubun üye cihazları arasında gezinin.
  • DeviceGroup üzerindeki bir parçaya gönderilen komutlar, üye cihazlar genelindeki tüm fanout işlemi tamamlandığında ve tüm temel komut başarıları veya başarısızlıkları toplandığında tamamlanır. Bir komut yalnızca ilişkili her üye cihaz için başarısız olursa veya tüm hedef cihazlar kullanılamıyorsa başarısız olur (HomeError hatası verir). Bu durumda, tek komut çağrısı söz dizimiyle eşleşen tek bir komut hatası gösterilir. En az bir üye cihaz komutu yürütürse grup komutu hata vermeden tamamlanır.

Grup bölümüne komut gönderme

Bir cihaz grubundaki tüm OnOffLightDeviceType ışıkları açmak için:

if let lightPart = await group.part(OnOffLightDeviceType.self),
   let onOffTrait = lightPart.matterTraits.onOffTrait,
   onOffTrait.supports(.on) {
  try await onOffTrait.on()
}

Birden fazla ilgili cihaz türünü de kontrol edebilirsiniz (örneğin, grupta OnOffTrait özelliğini destekleyen tüm ışık cihazı türlerini kapatma):

func onOffTrait(in group: DeviceGroup) async -> Matter.OnOffTrait? {
  if let light = await group.part(OnOffLightDeviceType.self) {
    return light.matterTraits.onOffTrait
  }
  if let light = await group.part(DimmableLightDeviceType.self) {
    return light.matterTraits.onOffTrait
  }
  if let light = await group.part(ColorTemperatureLightDeviceType.self) {
    return light.matterTraits.onOffTrait
  }
  if let light = await group.part(ExtendedColorLightDeviceType.self) {
    return light.matterTraits.onOffTrait
  }
  return nil
}

if let trait = await onOffTrait(in: group) {
  try await trait.off()
}

Komut göndermeden önce komut desteğini kontrol edebilir veya bir grup parçasındaki özellik sınırlarını okuyabilirsiniz (örneğin, kısılabilir ışık parçasında .moveToLevelWithOnOff özelliğini kontrol etme veya renk sıcaklığı ışık parçasında colorTempPhysicalMinMireds ve colorTempPhysicalMaxMireds özelliklerini okuma):

if let dimmableLight = await group.part(DimmableLightDeviceType.self),
   let levelTrait = dimmableLight.matterTraits.levelControlTrait,
   levelTrait.supports(.moveToLevelWithOnOff) {
  try await levelTrait.moveToLevelWithOnOff(
    level: 127,
    transitionTime: nil,
    optionsMask: [],
    optionsOverride: []
  )
}

if let colorLight = await group.part(ColorTemperatureLightDeviceType.self),
   let colorTrait = colorLight.matterTraits.colorControlTrait,
   let minMireds = colorTrait.attributes.colorTempPhysicalMinMireds,
   let maxMireds = colorTrait.attributes.colorTempPhysicalMaxMireds {
  let midMireds = UInt16((UInt32(minMireds) + UInt32(maxMireds)) / 2)
  try await colorTrait.moveToColorTemperature(
    colorTemperatureMireds: midMireds,
    transitionTime: 0,
    optionsMask: [],
    optionsOverride: []
  )
}