Android DSL के कॉन्सेप्ट

यह Android पर, ऑटोमेशन डीएसएल की बुनियादी अवधारणाओं की खास जानकारी है.

ऑटोमेशन के कॉम्पोनेंट

ऑटोमेशन में ये बुनियादी कॉम्पोनेंट शामिल होते हैं. आम तौर पर, इनका आकलन इसी क्रम में किया जाता है:

  1. स्टार्टर — यह उन शुरुआती शर्तों को तय करता है जिनसे ऑटोमेशन चालू होता है. जैसे, किसी एट्रिब्यूट में बदलाव होना. किसी ऑटोमेशन में एक स्टार्टर होना ज़रूरी है.
  2. शर्त — ऑटोमेशन चालू होने के बाद, आकलन करने के लिए कोई अतिरिक्त कंस्ट्रेंट. ऑटोमेशन की कार्रवाइयों को आगे बढ़ाने के लिए, शर्त में मौजूद एक्सप्रेशन का आकलन true के तौर पर होना चाहिए.
  3. कार्रवाई — वे कमांड या स्टेटस अपडेट जो सभी शर्तें पूरी होने पर किए जाते हैं.

उदाहरण के लिए, मान लें कि आपके पास एक ऐसा ऑटोमेशन है जो सूर्यास्त और सूर्योदय के बीच, कमरे में मौजूद टीवी के चालू होने पर, उस कमरे की लाइटें डिम कर देता है. इस उदाहरण में:

  1. स्टार्टर — टीवी चालू किया गया. यह टीवी एट्रिब्यूट के स्टेटस में बदलाव है.
  2. शर्त— टीवी जिस घर में है वहां का मौजूदा समय आंका जाता है.
  3. कार्रवाई — टीवी वाले कमरे की लाइटें डिम हो जाती हैं.

कमरे में मौजूद टीवी के चालू होने पर, ऑटोमेशन चालू हो जाएगा. हालांकि, ऑटोमेशन सिर्फ़ तब काम करेगा, जब "समय सूर्यास्त और सूर्योदय के बीच हो" की शर्त पूरी होगी.

बुनियादी स्ट्रक्चर के अलावा, Home APIs में मौजूद ऑटोमेशन में मेटाडेटा भी शामिल होता है. जैसे, name और description. डेवलपर और उपयोगकर्ता, इनकी मदद से ऑटोमेशन की पहचान कर सकते हैं .

नोड

Home APIs में, ऑटोमेशन का लॉजिकल स्ट्रक्चर नोड से मिलकर बनता है. नोड, अमूर्त और दोबारा इस्तेमाल किए जा सकने वाली इकाइयां होती हैं. ये इकाइयां, एंटिटी के व्यवहार या एक्ज़ीक्यूशन फ़्लो को दिखाती हैं. हर नोड में इनपुट वैरिएबल के साथ-साथ, आउटपुट वैरिएबल भी हो सकते हैं. इनका इस्तेमाल अन्य नोड कर सकते हैं.

टेबल: ऑटोमेशन नोड के टाइप
नोड नोड टाइप Kotlin में लागू करने का तरीका ब्यौरा
स्टार्टर व्यवहारजन्य StarterNodeDsl किसी एट्रिब्यूट का स्टेटस (कोई भी एट्रिब्यूट) बदलने पर, ऑटोमेशन शुरू करता है.
StateReader व्यवहारजन्य StateReaderNodeDsl किसी एट्रिब्यूट को पढ़ता है और आपको इसकी वैल्यू, शर्त वाले नोड में इस्तेमाल करने की अनुमति देता है.
कार्रवाई व्यवहारजन्य ActionNodeDsl एट्रिब्यूट के कमांड शुरू करता है.
अनुवर्ती एक्ज़ीक्यूशन फ़्लो SequentialFlow नेस्ट किए गए ऐक्शन नोड को क्रम से लागू करता है. यह डिफ़ॉल्ट एक्ज़ीक्यूशन का तरीका है.
पैरलल एक्ज़ीक्यूशन फ़्लो ParallelFlow नेस्ट किए गए ऐक्शन नोड को एक साथ लागू करता है.
शर्त एक्ज़ीक्यूशन फ़्लो ConditionNodeDsl लॉजिकल एक्सप्रेशन के आकलन के आधार पर, एक्ज़ीक्यूशन फ़्लो को शर्तों के हिसाब से बदलता है. शर्तें, स्टार्टर (स्टार्टर से जुड़ी शर्तें) या ग्लोबल (सभी स्टार्टर पर लागू होने वाली शर्तें) हो सकती हैं.
चुनें एक्ज़ीक्यूशन फ़्लो SelectFlow एक से ज़्यादा स्टार्टर को ऑटोमेशन चालू करने की अनुमति देता है.
IfFlow एक्ज़ीक्यूशन फ़्लो IfFlowDsl ज़्यादा से ज़्यादा एक कार्रवाई (या ब्रांच) को इस आधार पर रन करता है कि कौनसी शर्त (अगर कोई है) सही है. यह if-then-else स्टेटमेंट की तरह काम करता है.
एक्सप्रेशन वैल्यू Expression यह किसी एट्रिब्यूट की वैल्यू, कॉन्स्टैंट या लिटरल वैल्यू हो सकती है, और इसका आकलन, सूची, संख्या, बूलियन या स्ट्रिंग के तौर पर होना चाहिए.

व्यवहारजन्य नोड

स्टार्टर और ऐक्शन जैसे नोड, व्यवहारजन्य नोड होते हैं. स्टार्टर, डिवाइस के एट्रिब्यूट में बदलाव होने पर, ऑटोमेशन चालू करते हैं. ऐक्शन, डिवाइस के कमांड जारी करते हैं या एट्रिब्यूट अपडेट करते हैं.

व्यवहारजन्य नोड आम तौर पर, डिवाइस के एट्रिब्यूट से जुड़े होते हैं. साथ ही, ये अन्य नोड में इनपुट के तौर पर इस्तेमाल करने के लिए, एट्रिब्यूट का स्टेटस आउटपुट करते हैं.

एक्ज़ीक्यूशन फ़्लो नोड

कुछ नोड, एक्ज़ीक्यूशन फ़्लो को दिखाते हैं. जैसे, अनुवर्ती और पैरलल. इनमें से हर नोड में, व्यवहारजन्य नोड शामिल होते हैं. ये नोड, ऑटोमेशन को तय करते हैं.

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

क्रम से चलने वाले एक्ज़ीक्यूशन फ़्लो
पहली इमेज: अनुवर्ती ऑटोमेशन फ़्लो

पैरलल फ़्लो में, एक ही समय पर कई ऐक्शन नोड लागू हो सकते हैं. जैसे, एक ही समय पर कई लाइटें चालू करना. पैरलल फ़्लो के बाद आने वाले नोड, तब तक लागू नहीं होंगे, जब तक पैरलल फ़्लो की सभी ब्रांच पूरी नहीं हो जातीं.

एक साथ कई फ़्लो चलाने की सुविधा
दूसरी इमेज: पैरलल ऑटोमेशन फ़्लो

एक्ज़ीक्यूशन फ़्लो का एक और टाइप कंडीशन फ़्लो है. यह किसी एक्सप्रेशन के आकलन के आधार पर, एक्ज़ीक्यूशन फ़्लो को बदल सकता है.

उदाहरण के लिए, मान लें कि आपके पास एक ऐसा ऑटोमेशन है जो इस आधार पर कोई कार्रवाई करता है कि रात है या नहीं. कंडीशन नोड, दिन के समय की जांच करता है. इसके बाद, उस आकलन के आधार पर, सही एक्ज़ीक्यूशन पाथ को फ़ॉलो करता है.

शर्त के हिसाब से फ़्लो
तीसरी इमेज: कंडीशन फ़्लो

Select flow तब काम आता है, जब आपको एक से ज़्यादा स्टार्टर चाहिए, जो आपके ऑटोमेशन को चालू कर सकें. जब दो या उससे ज़्यादा स्टार्टर को select फ़्लो में शामिल किया जाता है, तो इनमें से कोई भी स्टार्टर, ऑटोमेशन को चालू कर सकता है.

उदाहरण के लिए, ऐसा ऑटोमेशन लिखा जा सकता है जो सूर्यास्त के समय, तापमान किसी तय थ्रेशोल्ड से ज़्यादा होने पर या चमक किसी थ्रेशोल्ड से ज़्यादा होने पर, ब्लाइंड को नीचे कर देता है. इनमें से हर स्थिति को तीन अलग-अलग स्टार्टर हैंडल करते हैं. इन तीनों को select फ़्लो में रैप किया जाएगा.

फ़्लो चुनें
चौथी इमेज: Select flow

If-then-else flow (IfFlow) की मदद से, ऑटोमेशन में शर्तों के हिसाब से एक्ज़ीक्यूशन की ब्रांचिंग की जा सकती है. condition नोड के उलट, if-then-else फ़्लो, किसी शर्त के सही होने पर, शर्तों के हिसाब से खास कार्रवाइयां करता है. अगर शर्त false होती है, तो पूरा ऑटोमेशन रुक जाता है. हालांकि, if-then-else फ़्लो, वैकल्पिक शर्तों या फ़ॉलबैक कार्रवाइयों पर वापस आ सकता है या ऑटोमेशन में आने वाले नोड पर जा सकता है. ज़्यादा जानकारी के लिए, शर्तों के हिसाब से एक्ज़ीक्यूशन देखें.

नेस्ट किए गए फ़्लो

जटिल ऑटोमेशन में, एक्ज़ीक्यूशन फ़्लो नोड को नेस्ट भी किया जा सकता है. उदाहरण के लिए, आपके पास एक ऐसा अनुवर्ती फ़्लो हो सकता है जो पैरलल फ़्लो को लागू करता है.

नेस्ट किए गए एक्ज़ीक्यूशन फ़्लो
पांचवी इमेज: नेस्ट किए गए एक्ज़ीक्यूशन फ़्लो

DSL नोड को नेस्ट किया जा सकता है और अपनी खास ज़रूरतों के हिसाब से अलग-अलग तरीकों से जोड़ा जा सकता है. इसके लिए, यहां दी गई टेबल में बताए गए कंस्ट्रेंट का पालन करना होगा. बिल्डर कॉलम, Kotlin के टाइपसेफ़ बिल्डर के दस्तावेज़ से लिंक होता है. इसमें हर तरह के नोड में इस्तेमाल की जा सकने वाली चीज़ों के बारे में जानकारी दी गई है.

टेबल: नोड को कैसे जोड़ा जा सकता है
नोड इसमें ये नोड टाइप और डेटा शामिल हो सकता है यह इनमें से किसी एक नोड टाइप में होना चाहिए
स्टार्टर एक्सप्रेशन Select, Sequential
ManualStarter Select, Sequential
StateReader एक्सप्रेशन (आम तौर पर, इसमें एट्रिब्यूट की वैल्यू शामिल होती है) IfFlow, Parallel, Sequential
कार्रवाई कमांड, एंटिटी, एक्सप्रेशन IfFlow, Parallel, Select, Sequential
Sequential IfFlow, Parallel, Select, Sequential
Parallel कार्रवाई IfFlow, Sequential
शर्त एक्सप्रेशन IfFlow, Parallel, Sequential
Select Condition, Sequential, Starter, ManualStarter Sequential. साथ ही, यह फ़्लो में पहला नोड होना चाहिए
IfFlow Action, Condition, Delay, IfFlow, Parallel, Sequential, StateReader, Suppression Sequential

ऑटोमेशन डीएसएल

Home APIs में, ऑटोमेशन को ऑटोमेशन डीएसएल (डोमेन-स्पेसिफ़िक लैंग्वेज) का इस्तेमाल करके तय किया जाता है. ऑटोमेशन डीएसएल को Kotlin डीएसएल (डोमेन-स्पेसिफ़िक लैंग्वेज) के तौर पर लागू किया जाता है. इसके लिए, Kotlin के टाइपसेफ़ बिल्डर का इस्तेमाल किया जाता है. इसे खास तौर पर, ऑटोमेशन टेंप्लेट तय करने के लिए डिज़ाइन किया गया है.

ऑटोमेशन कंपाइल होने पर, Kotlin के टाइपसेफ़ बिल्डर, Kotlin के डेटा क्लास जनरेट करते हैं. इसके बाद, इन्हें प्रोटोकॉल बफ़र JSON में सीरियल किया जाता है. इसका इस्तेमाल, Google की ऑटोमेशन सेवाओं को कॉल करने के लिए किया जाता है.

ऑटोमेशन डीएसएल, ऑटोमेशन बनाने की प्रोसेस को आसान और बेहतर बनाता है. यह Device API में मौजूद Matter स्टैंडर्ड एट्रिब्यूट और smart home एट्रिब्यूट के उसी डेटा मॉडल का इस्तेमाल करता है.

ऑटोमेशन डीएसएल, किसी उपयोगकर्ता के घर में मौजूद डिवाइस के खास इंस्टेंस के बजाय, अमूर्त डिवाइस टाइप के हिसाब से ऑटोमेशन का लॉजिक भी तय करता है. यह डेवलपर को इनपुट पैरामीटर देने की अनुमति देता है. इनका इस्तेमाल, रनटाइम के दौरान डिवाइस के असल इंस्टेंस के साथ-साथ, अन्य ज़रूरी पैरामीटर की वैल्यू तय करने के लिए किया जा सकता है.

डीएसएल का सिंटैक्स, Kotlin के सिंटैक्स जैसा होता है. साथ ही, यह Kotlin की तरह ही टाइपसेफ़ होता है. हालांकि, ऑटोमेशन डीएसएल में लिखा गया ऑटोमेशन, Kotlin में लिखे गए उसी ऑटोमेशन से ज़्यादा आसान और छोटा होता है.

उदाहरण

यहां ऑटोमेशन डीएसएल का इस्तेमाल करके लिखा गया एक ऑटोमेशन दिया गया है. यह ऑटोमेशन, किसी डिवाइस को चालू करता है:

val automation = automation {
  name = "MyFirstAutomation"
  description = "If light1 is on, turn on light2."
  isActive = true
  sequential {
    val onOffTrait = starter<_>(device1, OnOffLightDevice, OnOff)
    condition() { expression = onOffTrait.onOff equals true }
    action(device2, OnOffLightDevice) { command(OnOff.on()) }
  }
}

यह ऑटोमेशन बहुत बुनियादी है: जब device1 (एक लाइट) चालू होती है, तो onOff एट्रिब्यूट की वैल्यू true में बदल जाती है. इसके बाद, device2 को चालू करने के लिए, on() कमांड भेजा जाता है.

ऑटोमेशन में sequential नोड का इस्तेमाल किया जाता है. इससे पता चलता है कि इसके नोड, क्रम से रन होंगे.

sequential नोड में, starter, condition, और action जैसे व्यवहारजन्य नोड शामिल होते हैं. starter नोड के आउटपुट को, condition नोड में इस्तेमाल करने के लिए, किसी वैरिएबल को असाइन किया जाता है.