জটিল অটোমেশনের জন্য Android DSL গাইড

DSL গাইড - Android-এ বেসিক অটোমেশন-এ আলোচনা করা অটোমেশনের চেয়ে আরও জটিল অটোমেশন তৈরি করতে অটোমেশন DSL ব্যবহার করা যেতে পারে।

একাধিক অ্যাকশন সহ সিকোয়েন্সিয়াল

একাধিক অ্যাকশন সহ সিকোয়েন্সিয়াল

একটি অটোমেশন একাধিক কাজ করতে পারে। যেমন, একটি action নোডের পরিবর্তে, আপনার কাছে একাধিক action নোড থাকতে পারে, যা ক্রমানুসারে রান করে:

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

একাধিক সমান্তরাল অ্যাকশন সহ সিকোয়েন্সিয়াল

একাধিক সমান্তরাল অ্যাকশন সহ সিকোয়েন্সিয়াল

আপনি যদি parallel নোডে একাধিক action নোড রাখেন, তাহলে অ্যাকশনগুলি একই সাথে চালানো হয়।

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

parallel নোডের পরে আসা sequential নোডে যদি actionটি নোড থাকে, তাহলে parallel নোডের মধ্যে থাকা সব নোডের এক্সিকিউশন শেষ না হওয়া পর্যন্ত সেগুলি এক্সিকিউট হওয়ার জন্য অপেক্ষা করে।

শর্তসাপেক্ষ এক্সিকিউশন

ডিফল্ট হিসেবে, অটোমেশন নোডগুলি ক্রমানুসারে বা সমান্তরালভাবে এক্সিকিউট করে। আপনার যদি কন্ডিশনাল ব্রাঞ্চিং লজিক—রানটাইম কন্ডিশনের উপর ভিত্তি করে বিভিন্ন অ্যাকশন বা পাথ এক্সিকিউট করা—প্রয়োজন হয়, তাহলে if-then-else স্টেটমেন্ট ব্যবহার করুন, যা কন্ডিশনাল কন্ট্রোল ফ্লো DSL ব্লক ব্যবহার করে তৈরি করা হয়: ifThen, elseIf, এবং orElse.

স্ট্যান্ডার্ড condition নোড পুরো অটোমেশনকে গেট করে (যদি শর্তটি false-এ মূল্যায়ন করে, অটোমেশন অবিলম্বে কার্যকর করা বন্ধ করে দেয়), ifThen ব্লক ব্রাঞ্চিং কন্ট্রোল ফ্লো চালু করে:

  • condition নোড: এক্সপ্রেশন false হলে, সম্পূর্ণ অটোমেশন (বা বর্তমান এক্সিকিউশন পাথ) এক্সিকিউশন বন্ধ করে।
  • ifThen / elseIf / orElse: শর্তাবলী ক্রমানুসারে মূল্যায়ন করে। কোনও শর্ত false হলে, এক্সিকিউশন পরবর্তী elseIf ব্রাঞ্চ, orElse ফলব্যাক ব্রাঞ্চে চলে যায় অথবা কোনও শর্ত পূরণ না হলে অটোমেশনে পরবর্তী নোডে চালিয়ে যায়।

কোনও শর্তের ভিত্তিতে অ্যাকশন এক্সিকিউট করুন

ifThen ব্লক শর্তসাপেক্ষ এক্সপ্রেশন মূল্যায়ন করে। এক্সপ্রেশনটি true হিসেবে মূল্যায়ন করা হলে, ব্লকের মধ্যে নেস্ট করা DSL অ্যাকশন বা নোড এক্সিকিউট করা হয়। এটি 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 আর্গুমেন্ট নেয়, যা এক্সিকিউশন চালিয়ে যাওয়ার আগে কতক্ষণ পজ করতে হবে তা দেখায়। পজ করার সময়সীমা পাঁচ সেকেন্ড থেকে শুরু করে ২৪ ঘণ্টা পর্যন্ত হতে পারে।

যেমন, প্রতিটি টগলের মধ্যে পাঁচ সেকেন্ডের বিরতি সহ চারবার লাইট টগল করতে:

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 আর্গুমেন্ট ব্যবহার করুন যা পরবর্তী ট্রিগারে উত্তর দেওয়ার আগে কতক্ষণ অপেক্ষা করতে হবে তা দেখায়। দমন করার সময়সীমা পাঁচ সেকেন্ড থেকে শুরু করে ২৪ ঘণ্টা পর্যন্ত হতে পারে।

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 অন্তর্ভুক্ত।

কোনও অ্যাকশনে ট্রেট অ্যাট্রিবিউট সেট করা

কোনও বৈশিষ্ট্য অ্যাট্রিবিউটের ভ্যালু সেট করতে:

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