Android DSL गाइड

ऑटोमेशन बनाने के लिए, Automation DSL के अलग-अलग नोड का इस्तेमाल करने का तरीका समझने के लिए, यहां दी गई गाइड पढ़ें.

ऑटोमेशन DSL का पूरा कोड, automation नोड में रखा जाता है. automation नोड, Kotlin भाषा के बाहरी कॉन्टेक्स्ट और एम्बेड किए गए DSL कॉन्टेक्स्ट के बीच की सीमा तय करता है.

सीक्वेंशियल फ़्लो

सीक्वेंशियल फ़्लो, ऑटोमेशन फ़्लो का डिफ़ॉल्ट टाइप है.

सीक्वेंशल डीएसएल का उदाहरण

यहां Automation DSL का एक बहुत ही बुनियादी टेंप्लेट दिया गया है. इसमें सीक्वेंशियल फ़्लो का इस्तेमाल किया गया है. इसमें एक स्टार्टर, एक शर्त, और एक ऐक्शन शामिल है:


import com.google.home.automation.action
import com.google.home.automation.automation
import com.google.home.automation.condition
import com.google.home.automation.sequential
import com.google.home.automation.starter

...

automation {
  sequential {
    starter<_>(...)
    condition {...}
    action {...}
  }
}

इसमें अतिरिक्त नोड जोड़कर, इसे बेहतर बनाया जा सकता है.

स्टार्टर

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

ट्रेट एट्रिब्यूट के आधार पर स्टार्टर

ट्रेट एट्रिब्यूट के आधार पर स्टार्टर नोड की जानकारी देते समय, यह जानकारी दें:

  • डिवाइस
  • डिवाइस का वह टाइप जिससे ट्रेट जुड़ा है
  • ट्रेट
starter<_>(thermostat, TemperatureSensorDevice, TemperatureMeasurement)

डिवाइस टाइप पैरामीटर ज़रूरी है, क्योंकि इससे यह तय किया जा सकता है कि ऑटोमेशन, किसी डिवाइस के किस टाइप को टारगेट करता है. उदाहरण के लिए, किसी डिवाइस में FanDevice और HeatingCoolingUnitDevice, दोनों शामिल हो सकते हैं. इन दोनों में OnOff ट्रेट शामिल होता है. डिवाइस टाइप तय करने से, इस बारे में कोई भ्रम नहीं रहता कि डिवाइस का कौनसी चीज़ ऑटोमेशन को ट्रिगर करती है.

इवेंट के आधार पर स्टार्टर

किसी इवेंट के आधार पर स्टार्टर नोड की जानकारी देते समय, यह जानकारी दें:

  • डिवाइस
  • डिवाइस का वह टाइप जिससे ट्रेट जुड़ा है
  • इवेंट
starter<_>(doorBell, GoogleDoorbellDevice, DoorbellPressed)

पैरामीटर के साथ, स्ट्रक्चर और इवेंट के आधार पर स्टार्टर

कुछ इवेंट में पैरामीटर हो सकते हैं. इसलिए, इन पैरामीटर को स्टार्टर में भी शामिल करना ज़रूरी है.

उदाहरण के लिए, यह स्टार्टर, Time ट्रेट के ScheduledTimeEvent का इस्तेमाल करके, सुबह 7:00 बजे ऑटोमेशन को चालू करता है:

val earlyMorning = starter<_>(structure, Time.ScheduledTimeEvent) {
  parameter(Time.ScheduledTimeEvent.clockTime(
    LocalTime.of(7, 0, 0, 0)))
}

मौसम के आधार पर स्टार्टर

Weather ट्रेट का इस्तेमाल करके, स्टार्टर में मौजूदा या अनुमानित मौसम की स्थितियां तय की जा सकती हैं:

val weatherState = starter<_>(structure, trait = Weather)

ऑटोमेशन के उदाहरण वाले पेज पर, अगर बारिश होने की संभावना है, तो ब्लाइंड बंद करें देखें.

मैन्युअल स्टार्टर

मैन्युअल स्टार्टर, एक खास तरह का स्टार्टर होता है. इसकी मदद से, उपयोगकर्ता ऑटोमेशन को मैन्युअल तरीके से चला सकता है.

मैन्युअल स्टार्टर की जानकारी देते समय:

  • कोई ट्रेट या डिवाइस टाइप तय न करें.
  • ऐसा यूज़र इंटरफ़ेस (यूआई) एलिमेंट दें जो Automation.execute() को कॉल करता हो.

किसी select फ़्लो में, मैन्युअल स्टार्टर को किसी दूसरे स्टार्टर के साथ रखने पर, मैन्युअल स्टार्टर, दूसरे स्टार्टर को ओवरराइड कर देता है:

select {
  manualStarter()
  starter<_>(thermostat, TemperatureSensorDevice, TemperatureMeasurement)
}

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

मैन्युअल स्टार्टर को कंडीशनल स्टार्टर से अलग करना

ऑटोमेशन को इस तरह से स्ट्रक्चर करें, ताकि condition नोड, मैन्युअल स्टार्टर से चालू होने वाले ऑटोमेशन को ब्लॉक न करें. इसके लिए, दूसरे स्टार्टर को उसके condition के साथ, किसी अलग सीक्वेंशियल फ़्लो में रखें:

automation_graph {
  sequential {
    select {
      sequential {
        starter<_>(...)
        condition {...}
      }
      sequential {
        manualStarter()
      }
    }
    action {...}
  }
}

किसी एट्रिब्यूट की वैल्यू को रेफ़रंस करना

किसी एक्सप्रेशन में एट्रिब्यूट की वैल्यू का इस्तेमाल करने के लिए, यह सिंटैक्स इस्तेमाल करें.

stateReader के साथ:

val time = stateReader<_>(structure, Structure, Time)
val currTime = time.currentTime

starter के साथ:

val starterNode = starter<_>(device1, LaundryWasherDevice, OnOff)
condition() {
  expression = starterNode.onOff equals true
}

कंडीशन नोड और एक्सप्रेशन

कंडीशन नोड, फ़ैसला लेने के एक पॉइंट को दिखाता है. इससे यह तय होता है कि ऑटोमेशन जारी रहेगा या नहीं. किसी ऑटोमेशन में एक से ज़्यादा condition नोड हो सकते हैं. अगर किसी condition नोड का एक्सप्रेशन false के तौर पर दिखता है, तो पूरे ऑटोमेशन का एक्ज़ीक्यूशन खत्म हो जाता है.

condition नोड में, अलग-अलग ऑपरेटर का इस्तेमाल करके, कई कंडीशन के क्राइटेरिया को जोड़ा जा सकता है. हालांकि, एक्सप्रेशन की वैल्यू, बूलियन की एक वैल्यू होनी चाहिए. अगर नतीजे की वैल्यू true है, तो कंडीशन पूरी हो जाती है और ऑटोमेशन, अगले नोड का एक्ज़ीक्यूशन जारी रखता है. अगर वैल्यू false है, तो ऑटोमेशन का एक्ज़ीक्यूशन उसी पॉइंट पर रुक जाता है.

एक्सप्रेशन, Kotlin में मौजूद एक्सप्रेशन की तरह ही बनाए जाते हैं. इनमें प्रिमिटिव वैल्यू शामिल हो सकती हैं. जैसे, संख्याएं, वर्ण, स्ट्रिंग, और बूलियन. साथ ही, इनमें Enum वैल्यू भी शामिल हो सकती हैं. सब एक्सप्रेशन को ब्रैकेट में ग्रुप करने से, यह कंट्रोल किया जा सकता है कि उनका आकलन किस क्रम में किया जाए.

यहां एक condition का उदाहरण दिया गया है. इसमें कई सब एक्सप्रेशन को एक एक्सप्रेशन में जोड़ा गया है:

condition() {
  val expr1 = starterNode.lockState equals DlLockState.Unlocked
  val expr2 = stateReaderNode.lockState equals true

  val expr3 = occupancySensingDevice.occupied notEquals 0
  val expr4 = timeStateReaderNode
    .currentTime
    .between(
      timeStateReaderNode.sunsetTime,
      timeStateReaderNode.sunriseTime)
  expression = (expr1 and expr2) or (expr3 and expr4)
}

स्टार्टर के ज़रिए ऐक्सेस किए गए ट्रेट की वैल्यू को रेफ़रंस किया जा सकता है:

val starterNode = starter<_>(device, OnOff)
condition() { expression = starterNode.onOff equals true }

stateReader

condition नोड में, ट्रेट एट्रिब्यूट की वैल्यू को रेफ़रंस करने का दूसरा तरीका, stateReader नोड का इस्तेमाल करना है.

ऐसा करने के लिए, सबसे पहले stateReader नोड में ट्रेट एट्रिब्यूट की वैल्यू कैप्चर करें. stateReader, structure और ट्रेट को आर्ग्युमेंट के तौर पर लेता है:

import com.google.home.automation.stateReader
...
val filterMonitoringState = stateReader<_>(structure, ActivatedCarbonFilterMonitoring)

इसके बाद, condition नोड में stateReader को रेफ़रंस करें:

condition() {
  expression =
    filterMonitoringState.changeIndication
      .equals(ChangeIndicationEnum.Warning)
}

तुलना और लॉजिकल ऑपरेटर का इस्तेमाल करके, एक से ज़्यादा stateReaders का इस्तेमाल condition नोड में किया जा सकता है:

val armState = stateReader<_>(doorLock, DoorLockDevice, ArmDisarm )
val doorLockState = stateReader<_>(doorLock, DoorLockDevice, DoorLock)
condition() {
  expression =
    (armState.armState equals true)
    and
    (doorLockState.lockState equals true)
}

कंडीशन की अवधि

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

  condition {
    expression(lightStateReader.onOff == true)
    forDuration(Duration.ofMinutes(10))
  }

अवधि, पांच सेकंड से लेकर 24 घंटे तक हो सकती है.

ऐक्शन नोड

ऐक्शन नोड वह जगह है जहां ऑटोमेशन का काम होता है. इस उदाहरण में, ऐक्शन, AssistantBroadcast ट्रेट के broadcast() कमांड को कॉल करता है:

action(device, SpeakerDevice) {
  command(AssistantBroadcast.broadcast("Intruder detected!"))
}

स्टेटमेंट इंपोर्ट करें

ऑटोमेशन डेवलप करते समय, यह समझना मुश्किल हो सकता है कि Home APIs के अलग-अलग एलिमेंट को अपने कोड में कैसे इंपोर्ट किया जाए.

ट्रेट एट्रिब्यूट, ट्रेट के Companion ऑब्जेक्ट से इंपोर्ट किए जाते हैं:

import com.google.home.matter.standard.OnOff.Companion.onOff

ट्रेट से तय किए गए डेटा स्ट्रक्चर, उस ट्रेट क्लास से इंपोर्ट किए जाते हैं जिसका नाम "-Trait" से खत्म होता है:

import com.google.home.matter.standard.MediaPlaybackTrait.PlaybackStateEnum

ट्रेट कमांड, ट्रेट के Companion ऑब्जेक्ट से इंपोर्ट किए जाते हैं:

import com.google.home.matter.standard.Thermostat.Companion.setTemperatureSetpointHold