Android DSL गाइड

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

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

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

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

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

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


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)

स्ट्रक्चर और इवेंट पर आधारित स्टार्टर, जिसमें पैरामीटर शामिल हैं

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

उदाहरण के लिए, इस स्टार्टर में सुबह 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 के तौर पर दिखता है, तो पूरे ऑटोमेशन का काम बंद हो जाता है.

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

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

यहां 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)
}

शर्त की अवधि

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

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

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

ऐक्शन नोड

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

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

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

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

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