जटिल ऑटोमेशन के लिए Android DSL गाइड

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

एक से ज़्यादा कार्रवाइयों के साथ क्रम में चलने वाला

एक के बाद एक कई कार्रवाइयां करना

कोई ऑटोमेशन एक से ज़्यादा काम कर सकता है. उदाहरण के लिए, एक action नोड के बजाय, आपके पास कई action नोड हो सकते हैं. ये नोड, क्रम से चलते हैं:

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

एक साथ कई कार्रवाइयों के साथ क्रम में चलने वाला

एक साथ कई कार्रवाइयों के साथ क्रम में चलने वाला

अगर किसी parallel नोड में कई action नोड जोड़े जाते हैं, तो कार्रवाइयां एक साथ पूरी होती हैं.

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

अगर sequential नोड में action नोड हैं, जो parallel नोड के बाद आते हैं, तो वे तब तक एक्ज़ीक्यूट होने का इंतज़ार करते हैं, जब तक कि parallel नोड के सभी नोड एक्ज़ीक्यूट नहीं हो जाते.

शर्तों के मुताबिक कोड एक्ज़ीक्यूट करना

डिफ़ॉल्ट रूप से, ऑटोमेशन की सुविधा नोड को क्रम से या एक साथ चलाती है. अगर आपको कंडिशनल ब्रांचिंग लॉजिक की ज़रूरत है, तो if-then-else स्टेटमेंट का इस्तेमाल करें. इससे रनटाइम की शर्तों के आधार पर अलग-अलग कार्रवाइयां या पाथ लागू किए जा सकते हैं. ये स्टेटमेंट, कंडिशनल कंट्रोल फ़्लो डीएसएल ब्लॉक का इस्तेमाल करके बनाए जाते हैं: ifThen, elseIf, और orElse.

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

  • condition नोड: अगर एक्सप्रेशन false है, तो पूरे ऑटोमेशन (या मौजूदा एक्ज़ीक्यूशन पाथ) को एक्ज़ीक्यूट होने से रोकता है.
  • ifThen / elseIf / orElse: यह फ़ंक्शन, क्रम से शर्तों का आकलन करता है. अगर कोई शर्त false है, तो एक्ज़ीक्यूशन अगली elseIf ब्रांच, orElse फ़ॉलबैक ब्रांच पर चला जाता है या ऑटोमेशन में बाद के नोड पर जारी रहता है. ऐसा तब होता है, जब कोई शर्त पूरी नहीं होती.

किसी शर्त के आधार पर कार्रवाई करना

ifThen ब्लॉक, किसी कंडिशनल एक्सप्रेशन का आकलन करता है. अगर एक्सप्रेशन की वैल्यू true है, तो ब्लॉक में मौजूद डीएसएल कार्रवाइयां या नोड लागू किए जाते हैं. अगर इसकी वैल्यू false है, तो कार्रवाइयां छोड़ दी जाती हैं. साथ ही, ऑटोमेशन की प्रोसेस, क्रम में चलने वाले फ़्लो में अगले नोड पर जारी रहती है.

अगर आपको ऑटोमेशन में बाद के नोड को ब्लॉक या बंद किए बिना, सिर्फ़ शर्त के हिसाब से कोई कार्रवाई करनी है, तो अलग से मौजूद ifThen ब्लॉक का इस्तेमाल किया जा सकता है:

// When a door opens, turn on the light only if it is off,
// and always broadcast an announcement.
automation {
  sequential {
    val contactState = starter<_>(
      contactSensor,
      ContactSensorDevice,
      BooleanState,
    )
    val lightState = stateReader<_>(
      light,
      DimmableLightDevice,
      OnOff,
    )

    condition {
      // Door opened (contact sensor open)
      expression = contactState.stateValue equals false
    }

    // Conditionally turn on the light if it's off
    ifThen(lightState.onOff equals false) {
      action(light, DimmableLightDevice) { command(OnOff.on()) }
    }

    // Continue executing subsequent actions in the sequential flow
    action(structure) {
      command(AssistantBroadcast.broadcast("The door was opened."))
    }
  }
}

किसी शर्त के आधार पर अलग-अलग कार्रवाइयां करना

अगर आपको शर्त पूरी होने पर कार्रवाइयों का एक सेट और शर्त पूरी न होने पर कार्रवाइयों का दूसरा सेट चलाना है, तो ifThen(...) { ... } के बाद वैकल्पिक .orElse { ... } ब्लॉक को जोड़ें:

// When the door is unlocked, turn on the entryway light if it is off;
// otherwise, broadcast a welcome message.
automation {
  sequential {
    val doorLockEvent = starter<_>(
      doorLock,
      DoorLockDevice,
      LockOperationEvent,
    )
    val lightState = stateReader<_>(
      light,
      DimmableLightDevice,
      OnOff,
    )

    condition {
      expression =
        doorLockEvent.lockOperationType equals LockOperationTypeEnum.Unlock
    }

    ifThen(lightState.onOff equals false) {
      action(light, DimmableLightDevice) { command(OnOff.on()) }
    }.orElse {
      action(structure) {
        command(AssistantBroadcast.broadcast("Welcome home!"))
      }
    }
  }
}

एक से ज़्यादा शर्तों को क्रम से जोड़ना

एक के बाद एक कई शर्तों का आकलन करने के लिए, एक या उससे ज़्यादा वैकल्पिक .elseIf(...) { ... } ब्लॉक को चेन किया जा सकता है. जिस ब्रांच की शर्त का आकलन true के तौर पर किया जाता है उसे लागू किया जाता है. साथ ही, बाकी सभी ब्रांच को छोड़ दिया जाता है. अगर कोई भी शर्त true के तौर पर नहीं मिलती है, तो एक वैकल्पिक .orElse { ... } ब्लॉक लागू होता है (अगर दिया गया हो):

// Adjust climate controls based on room temperature changes.
automation {
  sequential {
    val tempStarter = starter<_>(
      tempSensor,
      TemperatureSensorDevice,
      TemperatureMeasurement,
    )

    // If temperature is high (>= 28°C / 2800 mC), switch thermostat to Cool mode
    ifThen(tempStarter.measuredValue greaterThanOrEquals 2800) {
      action(thermostat, ThermostatDevice) {
        command(
          SimplifiedThermostat.setSystemMode(
            SimplifiedThermostatSystemModeEnum.Cool
          )
        )
      }
    }.elseIf(tempStarter.measuredValue lessThan 1800) {
      // If temperature is low (< 18°C / 1800 mC), switch to Heat mode
      action(thermostat, ThermostatDevice) {
        command(
          SimplifiedThermostat.setSystemMode(
            SimplifiedThermostatSystemModeEnum.Heat
          )
        )
      }
    }.orElse {
      // Otherwise, turn on the fan
      action(fan, FanDevice) {
        command(OnOff.on())
      }
    }
  }
}

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

कंडिशनल ब्लॉक को अन्य ifThen, elseIf या orElse ब्लॉक में नेस्ट किया जा सकता है. साथ ही, इन्हें parallel, delayFor, और stateReader नोड के साथ जोड़ा जा सकता है.

ifThen, elseIf, और orElse ब्लॉक, अपने कॉन्टेंट को क्रम से चलने वाले फ़्लो के तौर पर लागू करते हैं. हर ब्रांच में, क्रम से चलने वाले किसी भी नोड को रखा जा सकता है. इनमें action, stateReader, parallel, delayFor, और नेस्ट किए गए ifThen ब्लॉक शामिल हैं.

विलंब

delayFor कीवर्ड का इस्तेमाल करके, ऑटोमेशन को कुछ समय के लिए रोका जा सकता है. यह कीवर्ड, java.time.Duration आर्ग्युमेंट लेता है. इससे यह पता चलता है कि ऑटोमेशन को फिर से शुरू करने से पहले, उसे कितनी देर तक रोकना है. वीडियो को रोकने की अवधि, पांच सेकंड से लेकर 24 घंटे तक हो सकती है.

उदाहरण के लिए, किसी लाइट को चार बार टॉगल करने के लिए, हर टॉगल के बीच पांच सेकंड का विराम दें:

sequential {
  action(light, OnOffLightDevice) { command(OnOff.toggle()) }
  delayFor(Duration.ofSeconds(5))
  action(light, OnOffLightDevice) { command(OnOff.toggle()) }
  delayFor(Duration.ofSeconds(5))
  action(light, OnOffLightDevice) { command(OnOff.toggle()) }
  delayFor(Duration.ofSeconds(5))
  action(light, OnOffLightDevice) { command(OnOff.toggle()) }
}

ट्रिगर को दबाना

ट्रिगर को दबाने की सुविधा से, ऑटोमेशन को शुरुआती ट्रिगर इवेंट के बाद, तय समय के लिए starter को अनदेखा करने की अनुमति मिलती है. उदाहरण के लिए, अगर ऑटोमेशन में कोई ऐसा starter है जो हलचल का पता लगाने वाली सुविधा से ट्रिगर होता है और आपने ट्रिगर को रोकने की अवधि पांच मिनट के लिए सेट की है, तो starter के ट्रिगर होने पर, वह अगले पांच मिनट तक फिर से ट्रिगर नहीं होगा. इससे ऑटोमेशन को बार-बार ट्रिगर होने से रोका जा सकता है.

अपने ऑटोमेशन में ट्रिगर को दबाने की सुविधा लागू करने के लिए, suppressFor कीवर्ड का इस्तेमाल करें. इसके साथ, java.time.Duration आर्ग्युमेंट का इस्तेमाल करें. इससे यह पता चलता है कि बाद के ट्रिगर का जवाब देने से पहले कितनी देर इंतज़ार करना है. यह अवधि पांच सेकंड से लेकर 24 घंटे तक हो सकती है.

automation {
  sequential {
    val starterNode = starter<_>(device, OccupancySensor, MotionDetection)
    suppressFor(Duration.ofMinutes(30))
    action(light, OnOffLightDevice) { command(OnOff.toggle()) }
}

ध्यान दें कि ट्रिगर को दबाने से, ऑटोमेशन में मौजूद उन सभी starters पर असर पड़ता है जो suppressFor से पहले आते हैं.

स्क्रिप्ट को रन करने की संख्या सीमित करना

ऑटोमेशन को चलाने की संख्या सीमित की जा सकती है.

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

इसके लिए, ऑटोमेशन के maxExecutionCount मेटाडेटा फ़ील्ड को सेट करें. यहां दिए गए उदाहरण में, ऑटोमेशन को सिर्फ़ एक बार लागू किया जा सकता है:

automation {
  // The automation can only be executed once.
  maxExecutionCount = 1
  // When the door lock state changes
  sequential {
    val doorLockEvent = starter<_>(doorLock, DoorLockDevice, LockOperationEvent)
    // if the door is unlocked
    condition() {
      expression = (doorLockEvent.lockOperationType equals LockOperationTypeEnum.Unlock)
    }
    // turn the light on
    action(light, DimmableLightDevice) { command(OnOff.on()) }
  }
}

ऑटोमेशन की प्रोसेस आखिरी बार पूरी होने और maxExecutionCount पर पहुंचने के बाद, ऑटोमेशन को तुरंत मिटा दिया जाता है. ऑटोमेशन के इतिहास की एंट्री, Google Home app (GHA) गतिविधि टैब में मौजूद रहती है. इसमें automation_id भी शामिल है.

किसी कार्रवाई में trait एट्रिब्यूट सेट करना

किसी ट्रेट एट्रिब्यूट की वैल्यू सेट करने के लिए:

  1. action नोड के अंदर एक update नोड बनाएं. इसमें update नोड के लिए, आर्ग्युमेंट के तौर पर काम की विशेषता शामिल करें:
    action(deviceReference, deviceType) {
      update(trait) {
    
      }
    }
  2. update नोड में, जिस एट्रिब्यूट में बदलाव करना है उसके लिए, म्यूटेटर फ़ंक्शन का इस्तेमाल करें और उसे नई वैल्यू पास करें. म्यूटेटर फ़ंक्शन का नाम बनाने के लिए:
    1. एट्रिब्यूट के नाम को कैपिटल लेटर में लिखें
    2. इसके पहले set शब्द जोड़ें.
    उदाहरण के लिए, defaultMoveRate नाम के एट्रिब्यूट को अपडेट करने के लिए, setDefaultMoveRate नाम के म्यूटेटर फ़ंक्शन का इस्तेमाल किया जाएगा.

ध्यान दें कि किसी update नोड में कई म्यूटेटर फ़ंक्शन हो सकते हैं. यहां एक उदाहरण दिया गया है, जिसमें दो एट्रिब्यूट अपडेट किए गए हैं:

action(device, Fan) {
  update(FanControl) {
    setPercentSetting(50u)
    setRockSetting(FanControlCluster.RockBitmap.rockUpDown)
  }
}