डिवाइस एपीआई को 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 पर डेटा मॉडल देखें.
गड़बड़ी ठीक करना
होम एपीआई में मौजूद कोई भी तरीका,
HomeException को थ्रो कर सकता है. इसलिए, हमारा सुझाव है कि आप सभी कॉल पर HomeException को पकड़ने के लिए, try-catch ब्लॉक का इस्तेमाल करें.
HomeException को हैंडल करते समय, गड़बड़ी के बारे में जानने के लिए इसके
error.code और
error.message फ़ील्ड देखें. इसमें उप-गड़बड़ी कोड भी हो सकते हैं. इसलिए,
getSubErrorCodes() तरीके को कॉल करें और नतीजे देखें.
अगर किसी अपवाद को हैंडल नहीं किया जाता है, तो आपका ऐप्लिकेशन क्रैश हो जाएगा.
ज़्यादा जानकारी के लिए, गड़बड़ी ठीक करना लेख पढ़ें.
उदाहरण के लिए, किसी डिवाइस को निर्देश भेजना लेख पढ़ें.
कॉल के सैंपल
डिवाइसों की सूची पाना
Structure इंस्टेंस का रेफ़रंस मिलने के बाद, devices() कॉल करने पर, आपको उस स्ट्रक्चर से ऐक्सेस किए जा सकने वाले डिवाइसों का Flow मिलता है:
// 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()
यहां से, हर डिवाइस की स्थिति को ऐक्सेस किया जा सकता है. साथ ही, डिवाइसों को निर्देश भेजे जा सकते हैं.
Home API के 1.8 वर्शन में, आपके पास यह विकल्प होता है कि एपीआई, मल्टीपार्ट डिवाइस के हर हिस्से को एक डिवाइस के तौर पर दिखाए. इसके लिए, devices() तरीके के enableMultipartDevices पैरामीटर को true पर सेट करें. ज़्यादा जानकारी के लिए, Android पर मल्टीपार्ट डिवाइस लेख पढ़ें.
डिवाइस की स्थिति को पढ़ना
डिवाइस की चालू/बंद होने की स्थिति बताने वाली विशेषता से 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 रिस्पॉन्स में इन स्ट्रिंग फ़ील्ड को शामिल किया जा सकता है:
जारी किया गया Connectivity Standards Alliance (Alliance) वेंडर आईडी:
"matterOriginalVendorId": "0xfff1",यह वेंडर के किसी प्रॉडक्ट का यूनीक आइडेंटिफ़ायर होता है:
"matterOriginalProductId": "0x1234",डिवाइस के लिए यूनीक आइडेंटिफ़ायर. इसे डिवाइस बनाने वाली कंपनी के हिसाब से बनाया जाता है:
"matterUniqueId": "matter-device-id",
इन स्ट्रिंग फ़ील्ड में वैल्यू डालते समय, अगर आपके पास Matter
वेंडर और प्रॉडक्ट आईडी हैं, तो उनका इस्तेमाल करें. अगर आप Alliance के सदस्य नहीं हैं और आपको ये आईडी असाइन नहीं किए गए हैं, तो 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 स्टैंडर्ड ट्रेट, लोकल राउटिंग की वजह से अब भी ऑनलाइन हो सकती हैं. हालांकि, क्लाउड पर आधारित ट्रेट ऑफ़लाइन हो जाएंगी.
डिवाइस का आईपी पता पाना
डिवाइस का आईपी पता ढूंढने के लिए, GeneralDiagnostics ट्रेट के networkInterfaces एट्रिब्यूट का इस्तेमाल करें. पते, बाइट ऐरे के तौर पर दिखाए जाते हैं. इन्हें स्टैंडर्ड IPv4 या IPv6 स्ट्रिंग के तौर पर फ़ॉर्मैट किया जा सकता है:
val ipAddresses =
trait.networkInterfaces?.flatMap { networkInterface ->
(networkInterface.ipv4Addresses + networkInterface.ipv6Addresses).mapNotNull { bytes ->
try {
java.net.InetAddress.getByAddress(bytes).hostAddress
} catch (e: java.net.UnknownHostException) {
null
}
}
} ?: emptyList()
किसी ट्रेट की नेटवर्क राउटिंग की जांच करना
किसी विशेषता के लिए इलाके की जानकारी, Home API में भी उपलब्ध होती है. dataSourceLocality से पता चलता है कि इस ट्रेट को रिमोट से (क्लाउड के ज़रिए), लोकल तौर पर (लोकल हब के ज़रिए) या पीयर-टू-पीयर (डिवाइस से डिवाइस पर सीधे, बिना हब के) रूट किया गया है.
UNSPECIFIED के लिए, जगह की जानकारी की वैल्यू 'जानकारी उपलब्ध नहीं है' हो सकती है. उदाहरण के लिए, जब कोई ऐप्लिकेशन बूट हो रहा हो और डिवाइस कनेक्टिविटी के लिए, हब या सर्वर तक न पहुंचा हो. इन डिवाइसों से संपर्क नहीं किया जा सकता. इसलिए, ये डिवाइस निर्देशों या इवेंट से मिलने वाले इंटरैक्शन के अनुरोधों को पूरा नहीं कर पाएंगे. ऐसे डिवाइसों को कैसे मैनेज करना है, यह क्लाइंट पर निर्भर करता है.
val onOffLocality = onOffTrait?.metadata?.sourceConnectivity?.dataSourceLocality
किसी डिवाइस के लिए नेटवर्क राउटिंग की जांच करना
कनेक्टिविटी की तरह, डिवाइस टाइप के हिसाब से इलाके की जांच की जाती है. जवाब में दी गई स्थिति, उस डिवाइस पर मौजूद सभी सुविधाओं के लिए इलाके की जानकारी का कॉम्बिनेशन होती है.
val lightLocality = dimmableLightDevice.metadata.sourceConnectivity.dataSourceLocality
MIXED की स्थिति भी PARTIALLY_ONLINE की कनेक्टिविटी की तरह ही होती है: कुछ सुविधाएं क्लाउड पर आधारित होती हैं, जबकि अन्य सुविधाएं स्थानीय होती हैं.
किसी डिवाइस का नाम बदलना
किसी डिवाइस का नाम बदलने के लिए, setName()
तरीके को कॉल करें:
mixerDevice.setName("Grendel")
अगर नाम में 60 यूनिकोड कोड पॉइंट (वर्ण) से ज़्यादा हैं, तो उन्हें छोटा कर दिया जाएगा. हालांकि, कोई गड़बड़ी नहीं दिखेगी. डेवलपर, लंबे नामों को मैनेज करने के लिए ज़िम्मेदार होते हैं. उदाहरण के लिए, वे यह तय कर सकते हैं कि उन्हें उपयोगकर्ताओं को यह सूचना देनी है या नहीं कि नाम छोटा कर दिया जाएगा.