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

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

import com.google.home.Home
import com.google.home.HomeDevice
import com.google.home.Id

Device API के साथ किसी खास डिवाइस टाइप या ट्रेट का इस्तेमाल करने के लिए, उन्हें अलग-अलग इंपोर्ट करना होगा.

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

import com.google.home.matter.standard.OnOff
import com.google.home.matter.standard.OnOffPluginUnitDevice

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

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

होम एपीआई में मौजूद कोई भी तरीका HomeException थ्रो कर सकता है. इसलिए, हमारा सुझाव है कि आप सभी कॉल पर HomeException को पकड़ने के लिए, try-catch ब्लॉक का इस्तेमाल करें.

HomeException को मैनेज करते समय, उसके code और message फ़ील्ड की जांच करें. इससे आपको गड़बड़ी के बारे में पता चलेगा.

अगर किसी अपवाद को हैंडल नहीं किया जाता है, तो आपका ऐप्लिकेशन क्रैश हो जाएगा.

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

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

कॉल के सैंपल

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

स्ट्रक्चर उपलब्ध होने पर, devices() कॉल से आपको उन डिवाइसों का फ़्लो मिलता है जिन्हें उस स्ट्रक्चर से ऐक्सेस किया जा सकता है:

// Get a flow of all devices accessible to the user
val allDevicesFlow: HomeObjectsFlow<HomeDevice> = home.devices()

// Calling list() on a HomeObjectsFlow returns the first Set of elements.
val allDevices: Set<HomeDevice> = allDevicesFlow.list()

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

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

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

// Assuming we have a device.
val deviceFlow = home.devices().itemFlow(myDeviceId)

val device = deviceFlow.first()

// Get a flow of a standard trait on the type. distinctUntilChanged() is needed to only trigger
// on the specific trait changes and not the whole type.
val onOffTraitFlow: Flow<OnOff?> =
  device.type(DimmableLightDevice).map { it.standardTraits.onOff }.distinctUntilChanged()

val onOffTrait: OnOff = onOffTraitFlow.first()!!

Kotlin फ़्लो फ़ंक्शन के बारे में ज़्यादा जानने के लिए, distinctUntilChanged देखें.

किसी ट्रेट सदस्यता में स्थिति को अमान्य करना

TraitStateInvalidation इंटरफ़ेस की मदद से, टारगेट डिवाइस की सदस्यता से हासिल की गई स्थिति को अमान्य किया जा सकता है. ऐसा उन मामलों में किया जाता है जहां स्थिति की जानकारी सही तरीके से नहीं दी जा रही है. यहां कुछ उदाहरण दिए गए हैं, जिनमें राज्य की जानकारी सही तरीके से नहीं दी गई है: Matter ट्रेट में "C" क्वालिटी वाले एट्रिब्यूट का इस्तेमाल करना या डिवाइस को लागू करने की वजह से, अचानक समस्या आ जाना.

यह एपीआई, मौजूदा ट्रेट की स्थिति को ज़बरदस्ती पढ़ता है और मौजूदा ट्रेट फ़्लो के ज़रिए नतीजे दिखाता है.

ट्रेट पाएं. इसके बाद, ट्रेट पर forceRead चलाएं:

val onOffTrait = device.?type(DimmableLightDevice)?.map{it.trait(OnOff)}.first()
onOffTrait.forceRead()

डिवाइस टाइप की सुविधाओं की सूची पाना

डिवाइस टाइप का इस्तेमाल, पढ़ने की सुविधाओं के लिए एंट्री पॉइंट के तौर पर किया जाना चाहिए. ऐसा इसलिए, क्योंकि ये किसी डिवाइस को उसके फ़ंक्शनल हिस्सों में बांटते हैं. जैसे, Matter में एंडपॉइंट.

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

डिमेबल लाइट डिवाइस टाइप के लिए उपलब्ध ट्रेट की सूची पाने के लिए:

// Get all types available on this device. Requires the types to be part of the registry during
// SDK initialization.
val typesFlow: Flow<Set<DeviceType>> = device.types()

// Get a snapshot of all types.
val types: Set<DeviceType> = typesFlow.first()

// Get the DimmableLightDevice instance from the set of types.
val dimmableLightDevice = types.filterIsInstance<DimmableLightDevice>().firstOrNull()

// Get all traits in the type + traits registered
val allTraits: Set<Trait> = dimmableLightDevice!!.traits()

डिवाइस में एक ही नाम वाली दो ट्रेट होने पर, ट्रेट कोलिज़न की दूसरी समस्या हो सकती है. उदाहरण के लिए, onOff, स्टैंडर्ड OnOff ट्रेट के इंस्टेंस को दिखा सकता है. इसके अलावा, यह मैन्युफ़ैक्चरर की ओर से तय की गई OnOff ट्रेट के इंस्टेंस को भी दिखा सकता है. यह तय करने के लिए कि किस ट्रेट का इस्तेमाल किया जाना है, डिवाइस के ज़रिए रेफ़र किए गए Trait इंस्टेंस से पहले, ज़रूरी शर्तें पूरी करने वाला नेमस्पेस होना चाहिए. स्टैंडर्ड ट्रेट के लिए, यानी कि Matter स्टैंडर्ड क्लस्टर से मिलती-जुलती ट्रेट के लिए, standardTraits का इस्तेमाल करें. Google की सुविधाओं के लिए, googleTraits का इस्तेमाल करें:

// Accessing standard traits on the type.
val onOffTrait: OnOff? = dimmableLightDevice.standardTraits.onOff
val levelControlTrait: LevelControl? = dimmableLightDevice.standardTraits.levelControl

किसी मैन्युफ़ैक्चरर के लिए उपलब्ध खास एट्रिब्यूट को ऐक्सेस करने के लिए, सीधे तौर पर उसका रेफ़रंस दें:

// Accessing a custom trait on the type.
val customTrait = dimmableLightDevice.trait(MyCustomTrait)

किसी खास सुविधा वाले डिवाइसों की सूची पाना

Kotlin में filter फ़ंक्शन का इस्तेमाल, एपीआई कॉल को और बेहतर बनाने के लिए किया जा सकता है. उदाहरण के लिए, घर में मौजूद उन सभी डिवाइसों की सूची पाने के लिए जिनमें चालू/बंद करने की सुविधा है:

// Get all devices that support OnOff
val onOffDevices: Flow<List<HomeDevice>> =
  home.devices().map { devices -> devices.filter { it.has(OnOff) } }

Home API में उपलब्ध सभी ट्रेट की पूरी सूची देखने के लिए, Trait इंटरफ़ेस देखें.

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

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

// Get a list of devices with similar device types (lights)
val lightDevices =
  home.devices().map { devices ->
    devices.filter {
      it.has(DimmableLightDevice) ||
        it.has(OnOffLightDevice) ||
        it.has(ColorTemperatureLightDevice) ||
        it.has(ExtendedColorLightDevice)
    }
  }

Home API में कई तरह के डिवाइस टाइप होते हैं, जो मुख्य डिवाइस टाइप को दिखा सकते हैं. उदाहरण के लिए, "लाइट" डिवाइस टाइप नहीं है. इसके बजाय, चार अलग-अलग तरह के डिवाइस हैं जो लाइट को दिखा सकते हैं. जैसा कि ऊपर दिए गए उदाहरण में दिखाया गया है. इसलिए, घर में मौजूद डिवाइसों के टाइप की ज़्यादा जानकारी पाने के लिए, फ़िल्टर किए गए फ़्लो में कई तरह के डिवाइस शामिल किए जाने चाहिए.

Home API में उपलब्ध डिवाइस टाइप की पूरी सूची देखने के लिए, DeviceType इंटरफ़ेस देखें.

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

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

// Get device basic information. All general information traits are on the RootNodeDevice type.
val basicInformation = device.type(RootNodeDevice).first().standardTraits.basicInformation!!
println("vendorName ${basicInformation.vendorName}")
println("vendorId ${basicInformation.vendorId}")
println("productId ${basicInformation.productId}")

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

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

  • कनेक्टिविटी स्टैंडर्ड्स अलायंस (सीएसए) ने वेंडर आईडी जारी किया है: "matterOriginalVendorId": "0xfff1",

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

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

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

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

{
  "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 में मौजूद डिवाइसों और सुविधाओं से मेटाडेटा जुड़ा होता है. इससे, ऐप्लिकेशन में उपयोगकर्ता अनुभव को मैनेज करने में मदद मिलती है.

होम एपीआई में मौजूद हर ट्रेट में एक sourceConnectivity प्रॉपर्टी होती है. इसमें ट्रेट के ऑनलाइन स्टेटस और जगह (लोकल या रिमोट राउटिंग) के बारे में जानकारी होती है.

किसी डिवाइस का मुख्य टाइप पाना

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

सबसे पहले, type() का इस्तेमाल करके, डिवाइस के टाइप पता करें. इसके बाद, मुख्य टाइप तय करें:

val types = device.types().first()
val primaryTypes = types.filter { it.metadata.isPrimaryType }

यह देखना कि कोई ट्रेट ऑनलाइन है या नहीं

किसी ट्रेट की कनेक्टिविटी की जांच करने के लिए, connectivityState() तरीके का इस्तेमाल करें:

val onOffConnectivity = onOffTrait?.metadata?.sourceConnectivity?.connectivityState

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

किसी डिवाइस के लिए कनेक्टिविटी की जांच करना

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

val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState

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

किसी ट्रेट की नेटवर्क राउटिंग की जांच करना

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

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

val onOffLocality = onOffTrait?.metadata?.sourceConnectivity?.dataSourceLocality

किसी डिवाइस के लिए नेटवर्क राउटिंग की जांच करना

कनेक्टिविटी की तरह, डिवाइस टाइप के हिसाब से जगह की जानकारी की जांच की जाती है. जवाब में दी गई स्थिति, उस डिवाइस पर मौजूद सभी सुविधाओं के लिए इलाके की जानकारी का कॉम्बिनेशन होती है.

val lightLocality = dimmableLightDevice.metadata.sourceConnectivity.dataSourceLocality

MIXED की स्थिति भी PARTIALLY_ONLINE कनेक्टिविटी की तरह ही होती है: कुछ सुविधाएं क्लाउड पर आधारित होती हैं, जबकि कुछ स्थानीय होती हैं.

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

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

mixerDevice.setName("Grendel")

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

एपीआई की सूची

Home का इंस्टेंस बन जाने के बाद, डिवाइस के इन एपीआई को इसके ज़रिए ऐक्सेस किया जा सकता है:

एपीआई ब्यौरा
devices() Google खाते से जुड़े सभी डिवाइसों को सभी स्ट्रक्चर में पाएं. यह एक HomeObjectsFlow दिखाता है, जो डेटा को वापस पाने और फ़िल्टर करने के ज़्यादा विकल्प देता है.

HomeDevice मिलने के बाद, इन एपीआई को ऐक्सेस किया जा सकता है:

एपीआई ब्यौरा
allCandidates() यह डिवाइस और उसके चाइल्ड के लिए, सभी ऑटोमेशन कैंडिडेट दिखाता है.
candidates() यह डिवाइस के लिए सभी ऑटोमेशन कैंडिडेट दिखाता है.
connectivityStateChanged डिवाइस की स्थिति में बदलाव होने का सबसे हाल का समय.
events(event) यह किसी इवेंट का फ़्लो दिखाता है.
events(trait) इस ट्रेट के हिसाब से, सभी इवेंट का फ़्लो मिलता है.
events(traits) इन ट्रेट के हिसाब से, सभी इवेंट का फ़्लो मिलता है.
getSourceConnectivity(trait) किसी खास ट्रेट के लिए मेटाडेटा पाएं. इससे SourceConnectivity मिलता है.
has(trait) देखें कि डिवाइस, अनुरोध की गई मौजूदा ट्रेट के साथ काम करता है या नहीं.
has(type) अगर डिवाइस में दिए गए टाइप का इस्तेमाल किया जा सकता है.
id डिवाइस का यूनीक सिस्टम आईडी.
isMatterDevice अगर डिवाइस को Matter से मैनेज किया जाता है.
name उपयोगकर्ता की ओर से दिया गया डिवाइस का नाम.
room() वह कमरा जिसमें डिवाइस को असाइन किया गया है. इससे Room मिलता है.
roomId उस रूम का आईडी जिसमें डिवाइस को असाइन किया गया है. यह Id दिखाता है.
sourceConnectivity डिवाइस की कनेक्टिविटी का सोर्स. इससे डिवाइस की कनेक्टिविटी की कुल स्थितियां और नेटवर्क की जगह की जानकारी मिलती है.
structure() वह स्ट्रक्चर जिसे डिवाइस असाइन किया गया है. इससे Structure मिलता है.
structureId यह उस स्ट्रक्चर का आईडी होता है जिससे डिवाइस को असाइन किया गया है. यह Id दिखाता है.
type(type) सीधे ऐक्सेस के लिए, टाइप की परिभाषा और उसमें मौजूद ट्रेट पाएं. यह हमेशा, एट्रिब्यूट का अपडेट किया गया स्नैपशॉट दिखाता है.
types() डिवाइस पर उपलब्ध सभी टाइप की सूची पाएं.