iOS के लिए डिवाइस और डिवाइस का मेटाडेटा ऐक्सेस करना

iOS के लिए, Home API की मदद से डिवाइस के एपीआई ऐक्सेस किए जा सकते हैं. अपने ऐप्लिकेशन में ये पैकेज इंपोर्ट करें:

import GoogleHomeSDK
import GoogleHomeTypes

ज़्यादा जानकारी के लिए, iOS पर डेटा मॉडल देखें.

गड़बड़ी ठीक करना

Home API के कुछ तरीकों से HomeError मिलता है. इसलिए, हमारा सुझाव है कि उन कॉल पर HomeError को पकड़ने के लिए, do-catch ब्लॉक का इस्तेमाल करें.

HomeError को ठीक करते समय, यह जानने के लिए कि क्या गड़बड़ी हुई है, इसके code और message फ़ील्ड देखें.

ठीक न की गई गड़बड़ियों की वजह से, आपका ऐप्लिकेशन क्रैश हो जाएगा.

ज़्यादा जानकारी के लिए, गड़बड़ी ठीक करना देखें.

उदाहरण के लिए, किसी डिवाइस को कोई निर्देश भेजना देखें.

कॉल के सैंपल

डिवाइसों की सूची पाना

Home ऑब्जेक्ट के रेफ़रंस के साथ, ऐक्सेस किए जा सकने वाले डिवाइसों की Query पाने के लिए, devices() को लागू करें. Query's batched() तरीके को कॉल करें. इससे, हर डिवाइस के मेटाडेटा में बदलाव होने पर, Home की मौजूदा स्थिति को दिखाने वाला एक सेट मिलता है. इसके अलावा, उपलब्ध डिवाइसों की Query.list() स्नैपशॉट पाने के लिए, को कॉल करें. यह एक सुविधाजनक तरीका है. इससे batched() स्ट्रीम की सदस्यता ली जाती है और पहली वैल्यू मिलती है. Query.stream() एक ऐसी स्ट्रीम बनाता है जो डिवाइस के मेटाडेटा में बदलाव होने पर नई वैल्यू देती है. जैसे, डिवाइस का नाम, कमरा या स्ट्रक्चर. इंटरनल तौर पर, यह batched() का इस्तेमाल करता है और सिर्फ़ बदली गई प्रॉपर्टी दिखाता है.

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

यहां से, हर डिवाइस की स्थितियों को ऐक्सेस किया जा सकता है और डिवाइसों को निर्देश भेजे जा सकते हैं.

Home API के वर्शन 1.8 के साथ, आपके पास यह विकल्प होता है कि एपीआई, कई हिस्सों वाले हर डिवाइस को एक डिवाइस के तौर पर दिखाए. इसके लिए, devices() तरीके के enableMultipartDevices पैरामीटर को true पर सेट करें. ज़्यादा जानकारी के लिए, iOS पर कई हिस्सों वाले डिवाइस देखें.

डिवाइस के टाइप पाना

किसी डिवाइस से जुड़े डिवाइस के टाइप पाने के लिए, डिवाइस की types प्रॉपर्टी पढ़ें. इससे DeviceTypeController मिलता है.

किसी खास डिवाइस टाइप के अपडेट पाने के लिए, DeviceTypeController.subscribe(_:) को कॉल करें:

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

अगर डिवाइस, बताए गए डिवाइस टाइप के साथ काम नहीं करता है, तो यह Empty Publisher दिखाता है, जो तुरंत पूरा हो जाता है.

अगर डिवाइस, किसी खास डिवाइस टाइप के साथ काम करता है, तो get() को कॉल करके उस टाइप का हैंडल पाया जा सकता है:

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

अगर डिवाइस, बताए गए टाइप के साथ काम नहीं करता है, तो यह nil दिखाता है.

DeviceTypeController.subscribeAll() का Publisher पाने के लिए, DeviceTypeCollection को कॉल करें. इस क्लास की मदद से, यह देखा जा सकता है कि डिवाइस में कोई खास डिवाइस टाइप है या नहीं:

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]
    }
}

डिवाइस टाइप की कोई ख़ासियत पाना

डिवाइस टाइप, डिवाइस की ख़ासियतें पढ़ने का एंट्री पॉइंट होते हैं. ऐसा इसलिए, क्योंकि ये डिवाइस को उसके काम के हिस्सों (जैसे, Matter में एंडपॉइंट) में बांटते हैं.Matter

अगर किसी डिवाइस में दो डिवाइस टाइप हैं और दोनों में एक ही ख़ासियत हो सकती है, तो ये डिवाइस टाइप की टक्कर को भी ध्यान में रखते हैं. उदाहरण के लिए, अगर कोई डिवाइस स्पीकर और डिमेबल लाइट, दोनों है, तो उसमें चालू/बंद करने की दो और लेवल कंट्रोल की दो ख़ासियतें होंगी.

डिवाइस की ख़ासियतों की टक्कर तब भी हो सकती है, जब किसी डिवाइस में एक ही नाम की दो ख़ासियतें हों. उदाहरण के लिए, onOff का मतलब, स्टैंडर्ड OnOff ख़ासियत का कोई इंस्टेंस हो सकता है. इसके अलावा, इसका मतलब, मैन्युफ़ैक्चरर की तय की गई OnOff ख़ासियत का कोई इंस्टेंस भी हो सकता है. यह पक्का करने के लिए कि किस ख़ासियत का इस्तेमाल किया जाना है, हर डिवाइस टाइप पर, डिवाइस की दो ख़ासियतों के कलेक्शन में से किसी एक के ज़रिए, किसी ख़ासियत का रेफ़रंस दें.

स्टैंडर्ड ख़ासियतों के लिए, यानी स्टैंडर्ड क्लस्टरMatter के जैसी ख़ासियतों के लिए, matterTraits का इस्तेमाल करें. उदाहरण के लिए, डिमेबल लाइट डिवाइस टाइप के लिए कोई खास ख़ासियत पाने के लिए:

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

Google की ख़ासियतों के लिए, googleTraits का इस्तेमाल करें:

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

मैन्युफ़ैक्चरर की किसी खास ख़ासियत को ऐक्सेस करने के लिए, traits प्रॉपर्टी के ज़रिए उसका रेफ़रंस दें. हालांकि, इससे पहले मैन्युफ़ैक्चरर के पैकेज का नाम डालें:

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
}

डिवाइस की स्थिति पढ़ना

डिवाइस की चालू/बंद करने की ख़ासियत से, OnOff एट्रिब्यूट की जांच करने का यह उदाहरण देखें:

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
}

किसी खास ख़ासियत वाले डिवाइसों की सूची पाना

किसी खास ख़ासियत वाले डिवाइसों की सूची पाने के लिए, आपको डिवाइसों, हर डिवाइस के डिवाइस टाइप, और हर डिवाइस टाइप की ख़ासियतों पर इटरेट करना होगा. उदाहरण के लिए, होम में मौजूद उन डिवाइसों की सूची पाने के लिए जिनमें चालू/बंद करने की ख़ासियत है:

// 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 में उपलब्ध सभी ख़ासियतों की पूरी सूची के लिए, iOS पर डिवाइस की ख़ासियतों का इंडेक्स देखें.

एक जैसे डिवाइस टाइप वाले डिवाइसों की सूची पाना

होम में मौजूद सभी लाइटों को दिखाने वाले डिवाइसों की सूची पाने के लिए:

// 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 में कई डिवाइस टाइप हो सकते हैं, जो किसी मुख्य डिवाइस टाइप को दिखा सकते हैं. उदाहरण के लिए, "लाइट" डिवाइस टाइप नहीं है. इसके बजाय, चार अलग-अलग डिवाइस टाइप हैं, जो लाइट को दिखा सकते हैं. जैसा कि पिछले उदाहरण में दिखाया गया है. इसलिए, होम में मौजूद डिवाइस के बड़े लेवल के टाइप की पूरी जानकारी पाने के लिए, कई डिवाइस टाइप शामिल किए जाने चाहिए.

Home API में उपलब्ध डिवाइस टाइप और उनकी ख़ासियतों की पूरी सूची के लिए, iOS पर इस्तेमाल किए जा सकने वाले डिवाइस टाइप देखें.

किसी डिवाइस के लिए वेंडर का नाम, वेंडर आईडी या प्रॉडक्ट आईडी पाना

BasicInformationTrait ख़ासियत में, किसी डिवाइस के लिए वेंडर आईडी, प्रॉडक्ट आईडी, प्रॉडक्ट का नाम, और सीरियल नंबर जैसी जानकारी शामिल होती है:

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

डिवाइस बनाने वाली कंपनियों के लिए, क्लाउड-टू-क्लाउड डिवाइस की पहचान करना

अगर आप डिवाइस बनाने वाली कंपनी हैं और Cloud-to-cloud डिवाइस बनाती हैं, तो अपने Cloud-to-cloud डिवाइसों की पहचान करने के लिए, BasicInformation ख़ासियत के ज़रिए, उनके SYNC जवाब में ये स्ट्रिंग फ़ील्ड शामिल किए जा सकते हैं:

  • Connectivity Standards Alliance (Alliance) ने वेंडर आईडी जारी किया है: "matterOriginalVendorId": "0xfff1",

  • एक प्रॉडक्ट आइडेंटिफ़ायर, जो किसी वेंडर के प्रॉडक्ट की यूनीक पहचान करता है: "matterOriginalProductId": "0x1234",

  • डिवाइस के लिए एक यूनीक आइडेंटिफ़ायर, जिसे मैन्युफ़ैक्चरर के हिसाब से बनाया जाता है: "matterUniqueId": "matter-device-id",

इन स्ट्रिंग फ़ील्ड को डालते समय, अगर आपके पास Matter वेंडर और प्रॉडक्ट आईडी हैं, तो उनका इस्तेमाल करें. अगर आप Alliance सदस्य नहीं हैं और आपको ये आईडी असाइन नहीं किए गए हैं, तो आप matterOriginalVendorId और matterOriginalProductId फ़ील्ड को खाली छोड़ सकते हैं . साथ ही, आइडेंटिफ़ायर के तौर पर matterUniqueId दें.

SYNC के जवाब के इस उदाहरण में, इन फ़ील्ड का इस्तेमाल दिखाया गया है:

{
  "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",
          }
        ]
      }
    ]
  }
}

ज़्यादा जानकारी के लिए, Cloud-to-cloud SYNC दस्तावेज़ देखें.

डिवाइस और डिवाइस की ख़ासियतों का मेटाडेटा

Home API में मौजूद डिवाइसों और डिवाइस की ख़ासियतों से जुड़ा मेटाडेटा होता है. इससे, किसी ऐप्लिकेशन में उपयोगकर्ता अनुभव को मैनेज करने में मदद मिलती है.

Home API में मौजूद हर डिवाइस की ख़ासियत में, sourceConnectivity प्रॉपर्टी होती है. इसमें, किसी डिवाइस की ख़ासियत की ऑनलाइन स्थिति और जगह (लोकल या रिमोट राउटिंग) के बारे में जानकारी होती है.

किसी डिवाइस का प्राइमरी टाइप पाना

कुछ डिवाइस, Home API के ज़रिए कई डिवाइस टाइप दिखा सकते हैं. यह पक्का करने के लिए कि उपयोगकर्ताओं को उनके डिवाइसों के लिए किसी ऐप्लिकेशन में सही विकल्प (जैसे, डिवाइस कंट्रोल और सुझाई गई ऑटोमेशन) दिखें, यह देखना ज़रूरी है कि कोई डिवाइस टाइप, डिवाइस का प्राइमरी टाइप है या नहीं.

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

यह देखना कि कोई डिवाइस की ख़ासियत ऑनलाइन है या नहीं

किसी डिवाइस की ख़ासियत की कनेक्टिविटी देखने के लिए, connectivityState प्रॉपर्टी पढ़ें:

let levelControlConnectivity =
  levelControlTrait.metadata.sourceConnectivity
  .connectivityState

अगर डिवाइस, इंटरनेट से कनेक्ट नहीं है, तो कुछ डिवाइस की ख़ासियतें ऑफ़लाइन दिख सकती हैं. आम तौर पर, ये Google smart home डिवाइस की ख़ासियतें होती हैं. ऐसा इसलिए होता है, क्योंकि ये डिवाइस की ख़ासियतें क्लाउड पर आधारित होती हैं और इनमें लोकल राउटिंग नहीं होती.

किसी डिवाइस की कनेक्टिविटी देखना

किसी डिवाइस की कनेक्टिविटी, डिवाइस टाइप के लेवल पर देखी जाती है. ऐसा इसलिए, क्योंकि कुछ डिवाइस कई डिवाइस टाइप के साथ काम करते हैं. दिखाई गई स्थिति, उस डिवाइस की सभी डिवाइस की ख़ासियतों की कनेक्टिविटी की स्थितियों का कॉम्बिनेशन होती है.

let lightConnectivity =
  dimmableLightDeviceType.metadata.sourceConnectivity
  .connectivityState

इंटरनेट कनेक्टिविटी न होने पर, मिक्स डिवाइस टाइप के मामले में partiallyOnline की स्थिति दिख सकती है. Matter स्टैंडर्ड डिवाइस की ख़ासियतें लोकल राउटिंग की वजह से अब भी ऑनलाइन हो सकती हैं. हालांकि, क्लाउड पर आधारित डिवाइस की ख़ासियतें ऑफ़लाइन होंगी.

partiallyOnline

किसी डिवाइस की ख़ासियत की नेटवर्क राउटिंग देखना

Home API में, किसी डिवाइस की ख़ासियत की जगह की जानकारी भी उपलब्ध होती है. dataSourceLocality से पता चलता है कि डिवाइस की ख़ासियत को रिमोट (क्लाउड के ज़रिए), लोकल (लोकल हब के ज़रिए) या पीयर-टू-पीयर (डिवाइस से डिवाइस पर सीधे, कोई हब नहीं) तरीके से राउट किया गया है.

जगह की जानकारी की अननोन वैल्यू unspecified हो सकती है. उदाहरण के लिए, जब कोई ऐप्लिकेशन बूट हो रहा हो और डिवाइस की कनेक्टिविटी के लिए वह अब तक किसी हब या सर्वर तक न पहुंचा हो. इन डिवाइसों तक नहीं पहुंचा जा सकता. साथ ही, ये डिवाइस, निर्देशों या इवेंट से मिलने वाले इंटरैक्शन के अनुरोधों को पूरा नहीं कर पाएंगे. क्लाइंट को यह तय करना होता है कि ऐसे डिवाइसों को कैसे मैनेज किया जाए.

let levelControlLocality =
  levelControlTrait.metadata.sourceConnectivity
  .dataSourceLocality

किसी डिवाइस की नेटवर्क राउटिंग देखना

कनेक्टिविटी की तरह, जगह की जानकारी भी डिवाइस टाइप के लेवल पर देखी जाती है. दिखाई गई स्थिति, उस डिवाइस की सभी डिवाइस की ख़ासियतों की जगह की जानकारी का कॉम्बिनेशन होती है.

let lightLocality =
  dimmableLightDeviceType.metadata.sourceConnectivity.dataSourceLocality

partiallyOnline कनेक्टिविटी के जैसे ही किसी मामले में, mixed की स्थिति दिख सकती है. ऐसा तब होता है, जब कुछ डिवाइस की ख़ासियतें क्लाउड पर आधारित होती हैं, जबकि कुछ लोकल होती हैं.

किसी डिवाइस का नाम बदलना

किसी डिवाइस का नाम बदलने के लिए, setName(_:) तरीके को कॉल करें:

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

किसी डिवाइस का नाम बदलने पर, ओरिजनल HomeDevice स्ट्रक्चर वही रहता है. साथ ही, बदलाव, अपडेट किए गए HomeDevice ऑब्जेक्ट में दिखता है.

अगर नाम, 60 यूनिकोड कोड पॉइंट (वर्ण) की सीमा से ज़्यादा है, तो उसे काट दिया जाएगा. साथ ही, कोई गड़बड़ी नहीं दिखेगी. डेवलपर, लंबे नामों को मैनेज करने के लिए ज़िम्मेदार होते हैं. उदाहरण के लिए, वे यह तय कर सकते हैं कि उपयोगकर्ताओं को यह बताना है या नहीं कि नाम काट दिए जाएंगे.