راهنمای Android DSL

از راهنمای زیر برای درک نحوه استفاده از گره‌های مختلف DSL خودکارسازی برای ساختن خودکارسازی استفاده کنید.

همه DSL خودکارسازی در یک گره automation قرار می‌گیرد. گره automation مرز بین بافت بیرونی زبان Kotlin و بافت DSL جاسازی‌شده را تشکیل می‌دهد.

جریان متوالی

جریان متوالی نوع پیش‌فرض جریان خودکارسازی است.

نمونه DSL متوالی

در اینجا یک الگوی 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 {...}
  }
}

این را می‌توان با افزودن گره‌های بیشتر پالایش کرد.

آغازگر

گره‌های آغازگر شرایط اولیه‌ای را که باعث فعال شدن خودکارسازی می‌شود تعریف می‌کنند. برای مثال، تغییر در وضعیت یا مقدار. خودکارسازی باید حداقل یک آغازگر داشته باشد، درغیراین‌صورت اعتبارسنجی آن ناموفق خواهد بود. برای افزودن بیش‌از یک آغازگر به خودکارسازی، باید از گره select استفاده کنید.

آغازگر براساس مشخصه ویژگی

هنگام اعلام گره آغازگری که براساس مشخصه ویژگی است، موارد زیر را مشخص کنید:

  • دستگاه
  • نوع دستگاهی که ویژگی به آن تعلق دارد
  • خصیصه
starter<_>(thermostat, TemperatureSensorDevice, TemperatureMeasurement)

پارامتر نوع دستگاه الزامی است زیرا به شما امکان می‌دهد مشخص کنید اتوماسیون به کدام نوع دستگاه در دستگاه اشاره دارد. برای مثال، ممکن است دستگاهی از FanDevice و HeatingCoolingUnitDevice تشکیل شده باشد که هر دو حاوی مشخصه OnOff هستند. با مشخص کردن نوع دستگاه، هیچ ابهامی درباره اینکه کدام بخش از دستگاه خودکارسازی را راه‌اندازی می‌کند وجود ندارد.

آغازگر براساس رویداد

هنگام اعلام گره آغازگر که براساس رویداد است، موارد زیر را مشخص کنید:

  • دستگاه
  • نوع دستگاهی که ویژگی به آن تعلق دارد
  • رویداد
starter<_>(doorBell, GoogleDoorbellDevice, DoorbellPressed)

آغازگر براساس ساختار و رویداد، با پارامترها

برخی‌از رویدادها می‌توانند پارامتر داشته باشند، بنابراین این پارامترها نیز باید در آغازگر گنجانده شوند.

برای مثال، این آغازگر از ScheduledTimeEvent ویژگی Time برای فعال کردن خودکارسازی در ساعت ۷:۰۰ صبح استفاده می‌کند:

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

آغازگر براساس آب‌وهوا

می‌توانید شرایط آب‌وهوایی فعلی یا پیش‌بینی‌شده را در آغازگر مشخص کنید، بااستفاده از مشخصه «آب‌وهوا»:

val weatherState = starter<_>(structure, trait = Weather)

اگر احتمال بارندگی وجود دارد، کرکره‌ها را ببند را در صفحه نمونه‌های خودکارسازی ببینید.

شروع‌کننده دستی

آغازگر دستی نوع خاصی از آغازگر است که به کاربر اجازه می‌دهد خودکارسازی را به‌صورت دستی اجرا کند.

هنگام اعلام آغازگر دستی:

  • ویژگی یا نوع دستگاه را مشخص نکنید.
  • عنصر میانای کاربری ارائه دهید که 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 باشند. گروه‌بندی زیرعبارت‌ها با پرانتز به شما امکان می‌دهد ترتیب ارزیابی آن‌ها را کنترل کنید.

در اینجا نمونه‌ای از 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)

سپس به stateReader در گره condition ارجاع دهید:

condition() {
  expression =
    filterMonitoringState.changeIndication
      .equals(ChangeIndicationEnum.Warning)
}

بااستفاده از مقایسه و عملگرهای منطقی، می‌توان از چند stateReaders در یک گره condition استفاده کرد:

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

مدت‌زمان می‌تواند از ۵ ثانیه تا ۲۴ ساعت باشد.

گره‌های کنش

گره کنش جایی است که کار خودکارسازی در آن انجام می‌شود. در این مثال، کنش فرمان broadcast() ویژگی AssistantBroadcast را فراخوانی می‌کند:

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

وارد کردن صورت‌حساب‌ها

هنگام توسعه خودکارسازی‌ها، همیشه مشخص نیست که چگونه عناصر مختلف Home APIs را به کد خود وارد کنید.

مشخصه‌های ویژگی از شیء 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