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

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

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 पर डेटा मॉडल देखें.

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

Home API में मौजूद कोई भी तरीका, 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 एट्रिब्यूट की जांच करने के उदाहरण पर नज़र डालते हैं. Home APIs के ट्रैट डेटा मॉडल का इस्तेमाल करके, इस ट्रैट को 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 generalDiagnosticsTrait = device.trait(GeneralDiagnostics).first()
generalDiagnosticsTrait.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 इंस्टेंस के पहले, क्वालीफ़ाइंग नेमस्पेस होना चाहिए. स्टैंडर्ड ट्रैट के लिए, standardTraits का इस्तेमाल करें. ये ट्रैट, Matter स्टैंडर्ड क्लस्टर से मिलते-जुलते होते हैं. 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 के एपीआई में उपलब्ध डिवाइस टाइप की पूरी सूची देखने के लिए, 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 रिस्पॉन्स में ये स्ट्रिंग फ़ील्ड शामिल किए जा सकते हैं:

  • Connectivity Standards Alliance (सीएसए) से मिला वेंडर आईडी: "matterOriginalVendorId": "0xfff1",

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

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

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

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

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

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

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

val types = device.types().first()
val primaryType = types.first { 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 कनेक्शन की स्थिति जैसी ही हो सकती है: कुछ ट्रैट क्लाउड-आधारित होते हैं, जबकि कुछ स्थानीय होते हैं.

एपीआई की सूची

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

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

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

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