Android के लिए Home APIs के ज़रिए, डिवाइस एपीआई को ऐक्सेस किया जा सकता है. इन पैकेज को अपने ऐप्लिकेशन में इंपोर्ट करें:
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 को मैनेज करते समय, उसके
error.code और
error.message फ़ील्ड देखें. इससे आपको गड़बड़ी के बारे में पता चलेगा. इसमें सब-गड़बड़ी कोड भी हो सकते हैं. इसलिए,
getSubErrorCodes() तरीके को कॉल करें और नतीजे देखें.
अगर किसी अपवाद को हैंडल नहीं किया जाता है, तो आपका ऐप्लिकेशन क्रैश हो जाएगा.
ज़्यादा जानकारी के लिए, गड़बड़ी ठीक करना लेख पढ़ें.
उदाहरण के लिए, किसी डिवाइस को निर्देश भेजना लेख पढ़ें.
कॉल के सैंपल
डिवाइसों की सूची पाना
स्ट्रक्चर उपलब्ध होने पर, 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 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
वेंडर और प्रॉडक्ट आईडी हैं, तो उनका इस्तेमाल करें. अगर आप सीएसए के सदस्य नहीं हैं और आपको ये आईडी असाइन नहीं किए गए हैं, तो 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 यूनिकोड कोड पॉइंट (वर्ण) से ज़्यादा हैं, तो उन्हें छोटा कर दिया जाएगा. हालांकि, कोई गड़बड़ी नहीं दिखेगी. डेवलपर, लंबे नामों को मैनेज करने के लिए ज़िम्मेदार होते हैं. उदाहरण के लिए, वे यह तय कर सकते हैं कि उन्हें उपयोगकर्ताओं को यह बताना है या नहीं कि नाम छोटा कर दिया जाएगा.