iOS için cihazlara ve cihaz meta verilerine erişme

Cihaz API'lerine iOS için Home API'leri üzerinden erişilebilir. Aşağıdaki paketleri uygulamanıza aktarın:

import GoogleHomeSDK
import GoogleHomeTypes

Daha fazla bilgi için iOS'te veri modeli başlıklı makaleyi inceleyin.

Hata işleme

Home API'lerindeki bazı yöntemler HomeError hatası verir. Bu nedenle, bu çağrılarda HomeError hatasını yakalamak için do-catch bloğu kullanmanızı öneririz.

HomeError ile ilgili işlem yaparken neyin yanlış gittiğini öğrenmek için code ve message alanlarını kontrol edin.

İşlenmeyen hatalar uygulamanızın kilitlenmesine neden olur.

Daha fazla bilgi için Hata işleme bölümüne bakın.

Örnek için Cihaza komut gönderme başlıklı makaleyi inceleyin.

Örnek aramalar

Cihaz listesi alma

Home nesnesine referans vererek devices() yöntemini çağırın ve erişilebilir cihazların Query listesini alın. Query'ın batched() yöntemini çağırın. Bu yöntem, her cihaz meta veri değişikliğinde evin mevcut durumunu yansıtan bir Set yayınlar. Mevcut cihazların anlık görüntüsünü almak için Query.list() komutunu da çağırabilirsiniz. Bu, batched() akışına abone olan ve ilk yayınlanan değeri döndüren kullanışlı bir yöntemdir. Query.stream(), adı, odası veya yapısı gibi cihaz meta verilerinde değişiklik olduğunda yeni değerler yayınlayan bir akış oluşturur. Dahili olarak bu, batched() kullanır ve yalnızca değiştirilen özellikleri yayınlar.

// Get a list of all devices accessible to the user
let homeDevices = try await self.home.devices().list()

Buradan her cihazın durumuna erişebilir ve cihazlara komut gönderebilirsiniz.

Home API'lerinin 1.8 sürümünde, devices() yönteminin enableMultipartDevices parametresini true olarak ayarlayarak API'nin her çok parçalı cihazı tek bir cihaz olarak temsil etmesini sağlayabilirsiniz. Daha fazla bilgi için iOS'te çok parçalı cihazlar başlıklı makaleyi inceleyin.

Cihazın türlerini alma

Bir cihazla ilişkili cihaz türlerini almak için cihazın types özelliğini okuyun. Bu özellik, DeviceTypeController döndürür.

Belirli bir cihaz türüyle ilgili güncellemeler için DeviceTypeController.subscribe(_:) yöntemini çağırın:

let devices = try await self.home.devices().list()
if let device = devices.first(where: { $0.id == myDeviceId }) {
  var receivedUpdate1 = false
  var receivedUpdate2 = false
  device.types.subscribe(OnOffLightDeviceType.self)
    .assertNoFailure()
    .sink { device in
      if !receivedUpdate1 {
        receivedUpdate1 = true
        Task {
          try await device.matterTraits.onOffTrait?.on()
        }
        return
      }
      if !receivedUpdate2 {
        receivedUpdate2 = true
        return
      }
      fatalError("Received unexpected update")
    }
}

Cihaz, belirtilen cihaz türünü desteklemiyorsa hemen tamamlanan bir Empty Publisher döndürür.

Cihaz belirli bir cihaz türünü destekliyorsa get() çağrısı yaparak bu tür için bir tanıtıcı alabilirsiniz:

if let device = devices.first(where: { $0.id == myDeviceId }) {
  let _ = await device.types.get(OnOffLightDeviceType.self)
}

Cihaz, belirtilen türü desteklemiyorsa nil değerini döndürür.

DeviceTypeCollection için Publisher almak üzere DeviceTypeController.subscribeAll() numaralı telefonu arayın. Bu sınıf, cihazın belirli bir cihaz türüne sahip olup olmadığını kontrol etmenizi sağlar:

if let device = devices.first(where: { $0.id == myDeviceId }) {
  device.types.subscribeAll()
    .assertNoFailure()
    .sink { types in
      let lightDeviceType = types[OnOffLightDeviceType.self]
      let fanDeviceType = types[FanDeviceType.self]
    }
}

Cihaz türü özelliği alma

Cihaz türleri, bir cihazı işlevsel parçalarına (Matter içindeki uç noktalar gibi) ayırdığı için özellikleri okumak için giriş noktasıdır.

Ayrıca, bir cihazda aynı özelliğe sahip iki cihaz türü varsa özellik çakışmalarını da hesaba katarlar. Örneğin, bir cihaz hem hoparlör hem de kısılabilir ışık ise iki Açma/Kapatma ve iki Seviye Kontrolü özelliğine sahip olur.

Bir cihazda aynı ada sahip iki özellik olduğunda başka bir özellik çakışması türü ortaya çıkabilir. Örneğin, onOff, standart OnOff özelliğinin bir örneğini veya üretici tarafından tanımlanan OnOff özelliğinin bir örneğini ifade edebilir. Hangi özelliğin amaçlandığıyla ilgili olası belirsizlikleri ortadan kaldırmak için her cihaz türündeki iki özellik koleksiyonundan biri aracılığıyla bir özelliğe referans verin.

Standart özellikler, yani Matter standart kümelerine benzer olanlar için matterTraits kullanın. Örneğin, Kısılabilir Işık cihaz türü için belirli bir özelliği almak istiyorsanız:

if let dimmableLightDeviceType =
  await device.types.get(DimmableLightDeviceType.self)
{
  // Accessing standard trait on the type.
  let levelControlTrait =
    dimmableLightDeviceType.matterTraits.levelControlTrait.self
}

Google özellikleri için googleTraits kullanın:

if let doorbellDeviceType = await device.types.get(GoogleDoorbellDeviceType.self) {
  // Accessing Google trait on the type.
  let doorbellPressTrait =
    doorbellDeviceType.traits[Google.DoorbellPressTrait.self]
}

Üreticiye özel bir özelliğe erişmek için traits mülkü üzerinden referans verin ancak üreticinin paket adını ekleyin:

let deviceType = await device1?.types.get(OnOffLightDeviceType.self)
// Accessing custom trait on the type.
if let spinnerTrait = deviceType?.traits[ExampleOrganization.SpinnerTrait.self] {
  let rpmVal = spinnerTrait.attributes.rpm
}

Cihaz durumunu okuma

Cihazın Açma/Kapatma özelliğinden OnOff özelliğini kontrol etme örneğine bakın:

let lightDevices = devices.filter {
  $0.types.contains(OnOffLightDeviceType.self)
}
let light1 = lightDevices.first
let lightDeviceTypeOptional = await light1?.types.get(OnOffLightDeviceType.self)
if let onOffTrait = lightDeviceTypeOptional?.matterTraits.onOffTrait {
  let onOffVal = onOffTrait.attributes.onOff
}

Belirli bir özelliğe sahip cihazların listesini alma

Belirli bir özelliğe sahip cihazların listesini almak için cihazları, her cihazın cihaz türlerini ve her cihaz türünün özelliklerini yinelemeniz gerekir. Örneğin, evde Açma/Kapatma özelliğine sahip tüm cihazların listesini almak için:

// Get all light devices that support levelControl
var levelControlDevices: [HomeDevice] = []
let allDevices = try await home.devices().list()
for device in allDevices {
  if let deviceType = await device.types.get(OnOffLightDeviceType.self) {
    if deviceType.traits.contains(Matter.LevelControlTrait.self) {
      levelControlDevices.append(device)
    }
  }
}

Home API'lerinde kullanılabilen özelliklerin tam listesi için iOS'te özellik dizini bölümüne bakın.

Benzer cihaz türlerine sahip cihazların listesini alma

Bir evdeki tüm ışıkları temsil eden cihazların listesini almak için:

// Get a list of devices with similar device types (lights)
let lightDevices =
  try await self.home.devices().list().compactMap {
    $0.types.contains(DimmableLightDeviceType.self)
      || $0.types.contains(OnOffLightDeviceType.self)
      || $0.types.contains(ColorTemperatureLightDeviceType.self)
      || $0.types.contains(ExtendedColorLightDeviceType.self)
  }

Home API'lerinde, temel cihaz türünü temsil edebilecek birden fazla cihaz türü vardır. Örneğin, "Işık" cihaz türü yoktur. Bunun yerine, önceki örnekte gösterildiği gibi bir ışığı temsil edebilecek dört farklı cihaz türü vardır. Bu nedenle, bir evdeki üst düzey cihaz türünün kapsamlı bir görünümünü elde etmek için birden fazla cihaz türü dahil edilmelidir.

Home API'lerinde kullanılabilen cihaz türlerinin ve özelliklerinin tam listesi için iOS'te desteklenen cihaz türleri bölümüne bakın.

Bir cihazın tedarikçi adını, tedarikçi kimliğini veya ürün kimliğini alma

BasicInformationTrait özelliği, bir cihazın Tedarikçi Kimliği, Ürün Kimliği, Ürün Adı ve Seri Numarası gibi bilgileri içerir:

guard
  let vendorName =
    basicInfoTrait.attributes.vendorName
else {
  fatalError("Failed to get vendorName")
}
guard
  let vendorID =
    basicInfoTrait.attributes.vendorID
else {
  fatalError("Failed to get vendorID")
}
guard
  let productID =
    basicInfoTrait.attributes.productID
else {
  fatalError("Failed to get productID")
}

Cihaz üreticileri için buluttan buluta cihaz tanımlama

Cihaz üreticisiyseniz ve Cloud-to-cloud cihazlar üretiyorsanız Cloud-to-cloud cihazlarınızı BasicInformation özelliğiyle tanımlamak için SYNC yanıtlarına şu dize alanlarını ekleyebilirsiniz:

  • Connectivity Standards Alliance (Alliance) tarafından verilen tedarikçi kimliği: "matterOriginalVendorId": "0xfff1",

  • Bir tedarikçinin ürününü benzersiz şekilde tanımlayan ürün tanımlayıcısı: "matterOriginalProductId": "0x1234",

  • Cihazın benzersiz tanımlayıcısı. Üreticiye özgü bir şekilde oluşturulur: "matterUniqueId": "matter-device-id",

Bu dize alanlarını girerken varsa Matter Tedarikçi ve Ürün Kimliklerinizi kullanın. Alliance üyesi değilseniz ve bu kimlikler size atanmadıysa matterOriginalVendorId ve matterOriginalProductId alanlarını boş bırakıp tanımlayıcı olarak matterUniqueId değerini girebilirsiniz.

Örnek SYNC yanıtı, bu alanların kullanımını gösterir:

{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "agentUserId": "1836.15267389",
    "devices": [
      {
        "id": "456",
        "type": "action.devices.types.LIGHT",
        "traits": [
          "action.devices.traits.OnOff",
          "action.devices.traits.Brightness",
          "action.devices.traits.ColorSetting",
        ],
        "willReportState": true,
        "deviceInfo": { ... },
        "matterOriginalVendorId": "0xfff1",
        "matterOriginalProductId": "0x1234",
        "matterUniqueId": "matter-device-id",
        "otherDeviceIds": [
          {
            "deviceId": "local-device-id",
          }
        ]
      }
    ]
  }
}

Daha fazla bilgi için Cloud-to-cloud SYNC belgelerine bakın.

Cihaz ve özellik meta verileri

Home API'lerindeki cihazlar ve özellikler, uygulamadaki kullanıcı deneyimini yönetmeye yardımcı olabilecek meta verilerle ilişkilendirilir.

Home API'lerindeki her özellik, özelliğin online durumu ve konumu (yerel veya uzaktan yönlendirme) hakkında bilgi içeren bir sourceConnectivity özelliği içerir.

Cihazın birincil türünü alma

Bazı cihazlar, Home API'leri aracılığıyla birden fazla cihaz türü sunabilir. Kullanıcılara bir uygulamada cihazları için uygun seçeneklerin (ör. cihaz kontrolü ve önerilen otomasyonlar) sunulmasını sağlamak amacıyla, cihaz türünün cihazın birincil türü olup olmadığını kontrol etmek faydalı olur.

if let deviceType =
  await device?.types.get(HumiditySensorDeviceType.self)
{
  if deviceType.metadata.isPrimaryType {
    print("Humidity Sensor is the primary type on this device.")
  } else {
    print("Humidity Sensor isn't the primary type on this device.")
  }
}

Bir özelliğin online olup olmadığını kontrol etme

Bir özelliğin bağlantısını kontrol etmek için connectivityState özelliğini okuyun:

let levelControlConnectivity =
  levelControlTrait.metadata.sourceConnectivity
  .connectivityState

Cihazın internet bağlantısı yoksa bazı özellikler (genellikle Google smart home özellikleri) çevrimdışı olarak gösterilebilir. Bunun nedeni, bu özelliklerin bulut tabanlı olması ve yerel yönlendirmeye sahip olmamasıdır.

Cihazın bağlantısını kontrol etme

Bazı cihazlar birden fazla cihaz türünü desteklediğinden, bir cihazın bağlantısı aslında cihaz türü düzeyinde kontrol edilir. Döndürülen durum, söz konusu cihazdaki tüm özelliklerin bağlantı durumlarının birleşimidir.

let lightConnectivity =
  dimmableLightDeviceType.metadata.sourceConnectivity
  .connectivityState

İnternet bağlantısı olmadığında karma cihaz türleri için partiallyOnline durumu görülebilir. Matter standart özellikleri, yerel yönlendirme nedeniyle hâlâ online olabilir ancak bulut tabanlı özellikler çevrimdışı olur.

Cihazın IP adresini alma

Cihazın IP adresini bulmak için GeneralDiagnosticsTrait'nin networkInterfaces özelliğini kullanın. Adresler Data nesneleri olarak döndürülür. Network çerçevesini kullanarak bunları standart IPv4 veya IPv6 dizeleri olarak biçimlendirebilirsiniz:

func getIpAddresses(trait: Matter.GeneralDiagnosticsTrait) -> [String] {
  let interfaces = trait.attributes.networkInterfaces ?? []
  var ipAddresses: [String] = []

  for interface in interfaces {
    for data in interface.iPv4Addresses {
      if let ipv4 = IPv4Address(data) {
        ipAddresses.append(String(describing: ipv4))
      }
    }
    for data in interface.iPv6Addresses {
      if let ipv6 = IPv6Address(data) {
        ipAddresses.append(String(describing: ipv6))
      }
    }
  }

  return ipAddresses
}

Bir özelliğin ağ yönlendirmesini kontrol etme

Özelliğin konumu Home API'lerinde de kullanılabilir. dataSourceLocality, özelliğin uzaktan (bulut üzerinden), yerel olarak (yerel bir hub üzerinden) veya eşler arası (cihazdan cihaza doğrudan, hub olmadan) yönlendirilip yönlendirilmediğini gösterir.

Bilinmeyen yerel ayar değeri unspecified, örneğin bir uygulama başlatılırken ve cihaz bağlantısı için henüz bir hub'a veya sunucuya ulaşmamışken mümkündür. Bu cihazlara erişilemiyor ve komutlardan veya etkinliklerden gelen etkileşim istekleri başarısız oluyor. Bu tür cihazların nasıl ele alınacağını belirlemek istemciye bağlıdır.

let levelControlLocality =
  levelControlTrait.metadata.sourceConnectivity
  .dataSourceLocality

Cihazın ağ yönlendirmesini kontrol etme

Bağlantı gibi yerellik de cihaz türü düzeyinde kontrol edilir. Döndürülen durum, o cihazdaki tüm özelliklerin yerelliğinin bir kombinasyonudur.

let lightLocality =
  dimmableLightDeviceType.metadata.sourceConnectivity.dataSourceLocality

mixed durumu, partiallyOnline bağlantısına benzer bir senaryoda gözlemlenebilir: Bazı özellikler bulut tabanlıyken diğerleri yereldir.

Cihazın adını değiştirme

Bir cihazın adını değiştirmek için setName(_:) yöntemini çağırın:

let updatedDevice = try await theDevice.setName("new device name")

Bir cihazın adı değiştirildiğinde orijinal HomeDevice yapısı aynı kalır ve değişiklik, döndürülen güncellenmiş HomeDevice nesnesine yansıtılır.

Adlar, 60 Unicode kod noktası (karakter) sınırını aşarsa kısaltılır ve hata gösterilmez. Uzun adların işlenmesinden geliştiriciler sorumludur. Örneğin, adların kısaltılacağı konusunda kullanıcıları bilgilendirmek isteyip istemediklerine karar verebilirler.

Bir cihazın grup üyeliğini kontrol etme

Fiziksel bir cihaz, bir veya daha fazla cihaz grubuna ait olabilir. Bir cihazın hangi gruplara ait olduğunu incelemek için cihazdaki GroupMembershipTrait değerini kontrol edin:

if let trait = await device.traits.get(Google.GroupMembershipTrait.self) {
  for groupId in trait.attributes.groupObjectIdsArray {
    print("Device belongs to group: \(groupId)")
  }
}

Bir DeviceGroup tarafından desteklenen cihaz türlerini incelemek ve gruba tek bir varlık olarak komut göndermek için Cihaz grubunu kontrol etme başlıklı makaleyi inceleyin.