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

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

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

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

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

import GoogleHomeSDK
import GoogleHomeTypes

automation (
...
) {

  starter(...)
  condition {...}
  action {...}
  action {...}
  action {...}

}

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

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

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

import GoogleHomeSDK
import GoogleHomeTypes

automation (
...
) {

  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.
typealias ContactSensorDevice = Matter.ContactSensorDeviceType
typealias BooleanStateTrait = Matter.BooleanStateTrait
typealias DimmableLightDevice = Matter.DimmableLightDeviceType
typealias OnOffTrait = Matter.OnOffTrait

automation {
  let contactState = starter(
    contactSensor,
    ContactSensorDevice.self,
    BooleanStateTrait.self
  )
  let lightState = stateReader(
    light,
    DimmableLightDevice.self,
    OnOffTrait.self
  )
  contactState
  lightState

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

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

  // Continue executing subsequent actions in the sequential flow
  action(structure) {
    Google.AssistantBroadcastTrait.broadcast(msg: "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.
typealias DoorLockDevice = Matter.DoorLockDeviceType
typealias DoorLockTrait = Matter.DoorLockTrait
typealias DimmableLightDevice = Matter.DimmableLightDeviceType
typealias OnOffTrait = Matter.OnOffTrait

automation {
  let doorLockEvent = starter(
    doorLock,
    DoorLockDevice.self,
    DoorLockTrait.LockOperationEvent.self
  )
  let lightState = stateReader(
    light,
    DimmableLightDevice.self,
    OnOffTrait.self
  )
  doorLockEvent
  lightState

  condition {
    doorLockEvent.lockOperationType.equals(.unlock)
  }

  ifThen(lightState.onOff.equals(false)) {
    action(light, DimmableLightDevice.self) {
      OnOffTrait.on()
    }
  }.orElse {
    action(structure) {
      Google.AssistantBroadcastTrait.broadcast(msg: "Welcome home!")
    }
  }
}

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

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

// Adjust climate controls based on room temperature changes.
typealias TemperatureSensorDeviceType = Matter.TemperatureSensorDeviceType
typealias TemperatureMeasurementTrait = Matter.TemperatureMeasurementTrait
typealias ThermostatDeviceType = Matter.ThermostatDeviceType
typealias SimplifiedThermostatTrait = Google.SimplifiedThermostatTrait
typealias FanDeviceType = Matter.FanDeviceType
typealias OnOffTrait = Matter.OnOffTrait

automation {
  let tempStarter = starter(
    tempSensor,
    TemperatureSensorDeviceType.self,
    TemperatureMeasurementTrait.self
  )
  tempStarter

  // If temperature is high (>= 28°C / 2800 mC), switch thermostat to Cool mode
  ifThen(tempStarter.measuredValue.greaterThanOrEquals(2800)) {
    action(thermostat, ThermostatDeviceType.self) {
      SimplifiedThermostatTrait.setSystemMode(systemMode: .cool)
    }
  }.elseIf(tempStarter.measuredValue.lessThan(1800)) {
    // If temperature is low (< 18°C / 1800 mC), switch to Heat mode
    action(thermostat, ThermostatDeviceType.self) {
      SimplifiedThermostatTrait.setSystemMode(systemMode: .heat)
    }
  }.orElse {
    // Otherwise, turn on the fan
    action(fan, FanDeviceType.self) {
      OnOffTrait.on()
    }
  }
}

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

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

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

विलंब

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

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

typealias OnOffLightDevice = Matter.OnOffLightDeviceType
typealias OnOffTrait = Matter.OnOffTrait

sequential {
  action(light, OnOffLightDevice.self) { OnOffTrait.toggle() }
  delay(for:.seconds(5))
  action(light, OnOffLightDevice.self) { OnOffTrait.toggle() }
  delay(for:.seconds(5))
  action(light, OnOffLightDevice.self) { OnOffTrait.toggle() }
  delay(for:.seconds(5))
  action(light, OnOffLightDevice.self) { OnOffTrait.toggle() }
}

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

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

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

typealias OccupancySensorDevice = Matter.OccupancySensorDeviceType
typealias OnOffLightDevice = Matter.OnOffLightDeviceType
typealias MotionDetectionTrait = Google.MotionDetectionTrait
typealias OnOffTrait = Matter.OnOffTrait

automation {
  let starterNode = starter(device, OccupancySensorDevice.self, MotionDetectionTrait.self)
  starterNode
  suppress(for: .seconds(30 * 60)) // 30 minutes
  action(light, OnOffLightDevice.self) { OnOffTrait.toggle() }
}

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

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

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

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

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

import GoogleHomeSDK
import GoogleHomeTypes

typealias RoboticVacuumCleanerDevice = Matter.RoboticVacuumCleanerDeviceType
typealias RvcRunModeTrait = Matter.RvcRunModeTrait
typealias AreaPresenceStateTrait = Google.AreaPresenceStateTrait

let draftAutomation = automation(
  name: "Vacuum home away",
  description: "Run the vacuum once when everyone is away.",
  maxExecutionCount: 1
) {
  let homeAwayState = starter(structure, AreaPresenceStateTrait.self)
  homeAwayState

  condition {
    homeAwayState.presenceState.equals(.presenceStateVacant)
  }

  action(vacuum, RoboticVacuumCleanerDevice.self) {
    RvcRunModeTrait.changeToMode(newMode: 1)
  }
}

ऑटोमेशन की प्रोसेस आखिरी बार पूरी होने और 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 नोड में कई म्यूटेटर फ़ंक्शन हो सकते हैं. यहां एक उदाहरण दिया गया है, जिसमें दो एट्रिब्यूट अपडेट किए गए हैं:

typealias FanDeviceType = Matter.FanDeviceType
typealias FanControlTrait = Matter.FanControlTrait

action(fan, FanDeviceType.self) {
  update(FanControlTrait.self) {
    $0.setFanMode(.on)
  }
}