DSL गाइड - बेसिक ऑटोमेशन

ऑटोमेशन बनाने के लिए, अलग-अलग ऑटोमेशन डीएसएल नोड का इस्तेमाल कैसे किया जा सकता है, यह समझने के लिए नीचे दी गई गाइड का इस्तेमाल करें.

ऑटोमेशन डीएसएल को एक ही automation नोड में रखा जाता है. automation नोड, बाहरी Kotlin भाषा के कॉन्टेक्स्ट और एम्बेड किए गए 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 {...}
  }
}

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

नए

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • किसी खास तरह के डिवाइस या ट्रैट के बारे में न बताएं.
  • ऐसा यूज़र इंटरफ़ेस (यूआई) एलिमेंट दें जो 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 के तौर पर किया जाता है, तो पूरे ऑटोमेशन का EXECUTION बंद हो जाता है.

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)
}

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

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

शर्त की अवधि

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

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

यह अवधि एक से 30 मिनट तक की हो सकती है.

ऐक्शन नोड

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

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

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

ऑटोमेशन बनाते समय, यह हमेशा साफ़ तौर पर नहीं पता चलता कि Home के एपीआई के अलग-अलग एलिमेंट को अपने कोड में कैसे इंपोर्ट किया जाए.

ट्रैट एट्रिब्यूट, ट्रैट के 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