डिवाइस एपीआई को 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 पर डेटा मॉडल देखें.
गड़बड़ी ठीक करना
Home APIs में मौजूद किसी भी तरीके से
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 एट्रिब्यूट की वैल्यू की जांच करने का उदाहरण देखें. होम एपीआई के ट्रेट डेटा मॉडल का इस्तेमाल करके, इस ट्रेट को 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 में मौजूद डिवाइसों और उनकी सुविधाओं से जुड़ा मेटाडेटा होता है. इससे, ऐप्लिकेशन में उपयोगकर्ता अनुभव को मैनेज करने में मदद मिलती है.
Home APIs में मौजूद हर ट्रेट में एक 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
PARTIALLY_ONLINE कनेक्टिविटी की तरह ही, MIXED की स्थिति भी इसी तरह के किसी मामले में दिख सकती है: कुछ सुविधाएं क्लाउड पर आधारित होती हैं, जबकि अन्य स्थानीय होती हैं.
किसी डिवाइस का नाम बदलना
किसी डिवाइस का नाम बदलने के लिए, setName()
तरीके को कॉल करें:
mixerDevice.setName("Grendel")
अगर नाम में 60 यूनिकोड कोड पॉइंट (वर्ण) से ज़्यादा हैं, तो उन्हें छोटा कर दिया जाएगा. हालांकि, कोई गड़बड़ी नहीं दिखेगी. डेवलपर, लंबे नामों को मैनेज करने के लिए ज़िम्मेदार होते हैं. उदाहरण के लिए, वे यह तय कर सकते हैं कि उन्हें उपयोगकर्ताओं को यह बताना है या नहीं कि नाम छोटा कर दिया जाएगा.
किसी डिवाइस के लिए ग्रुप की सदस्यता देखना
किसी फ़िज़िकल डिवाइस को एक या उससे ज़्यादा डिवाइस ग्रुप में शामिल किया जा सकता है. यह देखने के लिए कि कोई डिवाइस किन ग्रुप में शामिल है, डिवाइस पर मौजूद GroupMembership ट्रेट देखें:
val groupIds = device.trait(GroupMembershipTrait)?.groupObjectIds.orEmpty()
for (groupId in groupIds) {
println("HomeAPI", "Device belongs to group: $groupId")
}
इसके उलट, किसी DeviceGroup से जुड़े सभी सदस्य डिवाइसों को देखा जा सकता है. इसके लिए, DeviceGroup पर devices() फ़्लो को कॉल करें:
group.devices(enableMultipartDevices = true).collect { members ->
println("HomeAPI", "Group contains ${members.size} devices")
}