نمای کلی Automation API در Android

خودکارسازی‌ها راهی برای خودکار کردن تکالیف و تنظیمات دستگاه در خانه است. خودکارسازی‌ها در بوم‌سازگان Google Home به‌عنوان «روال‌ها» در Google Home app (GHA) و ازطریق automation script editor در Google Home for web دردسترس بوده‌اند.

اکنون «خودکارسازی‌ها» در بوم‌سازگان Google Home ازطریق Home APIs برای Android دردسترس است. این روال‌ها از همان مفاهیم پایه‌ای استفاده می‌کنند که در «روال‌های» GHA و script editor استفاده می‌شود، اما با ویژگی‌ها و قابلیت‌های بهبودیافته‌ای که فقط ازطریق Home API امکان‌پذیر است، ازجمله:

  • دسترسی به همه ویژگی‌های استاندارد Matter و smart home برای دستگاه، همان‌طور که در Home API ارائه شده است.
  • پشتیبانی از جریان‌های اجرای متوالی، موازی، و انتخابی.

خودکارسازی‌ها بااستفاده از Automation DSL نوشته می‌شوند که یک زبان مختص دامنه است و برای ساختن خودکارسازی‌ها در Kotlin طراحی شده است.

هر ویژگی و نوعی که قصد دارید در برنامه‌تان با Device & Structure یا Automation API استفاده کنید باید در مقداردهی اولیه ثبت شود. راه‌اندازی خانه در Android را ببینید.

راهنمایی برای زمانی که کاربر اجازه‌های کامل را لغو می‌کند

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

هربار که برنامه شروع می‌شود، حتماً بررسی کنید که اجازه‌ها همچنان فعال باشند. اگر لغو شده‌اند، مطمئن شوید که همه داده‌های قبلی، ازجمله داده‌های ذخیره‌شده در حافظه نهان برنامه، برداشته شده باشند.

وقتی دسترسی به ساختمان لغو شود، StructureAccessRevokedEvent به پسای ابری شما ارسال می‌شود. برای گردش کار لغو برنامه تلفن همراه و فضای ابری شریک سرتاسر، به ساختار واگذاری‌ها مراجعه کنید.

سفر توسعه‌دهنده

Automation API بخشی از یک سفر توسعه بزرگ‌تر است. این مرحله پس‌از ادغام میاناهای برنامه‌سازی کاربردی «ساختار» و «دستگاه» انجام می‌شود تا اطمینان حاصل شود که وقتی کاربر می‌خواهد از خودکارسازی استفاده کند، بتواند این کار را انجام دهد.

  1. توسعه‌دهنده اتوماسیون خود را برنامه‌ریزی می‌کند و آن را بااستفاده از Automation DSL تعریف می‌کند.
  2. توسعه‌دهنده تعریف خودکارسازی را در برنامه Kotlin Android جاسازی می‌کند.
  3. برنامه براساس اطلاعات مربوط به دستگاه‌های کاربر، ازجمله ویژگی‌ها، مشخصه‌ها، فرمان‌ها، و رویدادهایی که بااستفاده از Discovery API یا Device API جمع‌آوری شده‌اند، خودکارسازی‌ها را به کاربر ارائه می‌دهد.
    1. با Discovery API، برنامه می‌تواند پیش‌نویس خودکارسازی سفارشی‌شده‌ای برای انواع دستگاه و ویژگی‌های موجود در ساختار کاربر، با یا بدون ورودی کاربر، ایجاد کند.
    2. Device API می‌تواند بیشتر اطلاعاتی را که Discovery API ارائه می‌دهد ارائه کند، اما برای موارد استفاده خودکارسازی بهینه‌سازی نشده است. برای جزئیات بیشتر، مقایسه Device API و Discovery API را ببینید.
  4. برنامه، خودکارسازی واقعی را که به ساختار انتخاب‌شده مرتبط است ایجاد می‌کند.
  5. اکنون خودکارسازی در ساختار کاربر دردسترس است و می‌توان آن را بااستفاده از روش‌های Structure API اجرا یا حذف کرد.

کاربر می‌تواند هر زمان که بخواهد نمونه‌های جدیدی از خودکارسازی ایجاد کند و ساختار متفاوتی را انتخاب کند یا، بسته به منطق برنامه، شاید مجموعه متفاوتی از دستگاه‌ها را انتخاب کند. هربار که این کار را انجام می‌دهند، برنامه نمونه جدیدی از خودکارسازی را تولید می‌کند.

در ساده‌ترین سناریو، ممکن است به کاربران خود یک خودکارسازی ازپیش تعریف‌شده پیشنهاد دهید که یک کار نسبتاً ساده را انجام می‌دهد. همچنین می‌توانید چارچوب خودکارسازی‌ای را ارائه دهید که کاربر آن را برای برآورده کردن نیازهایش سفارشی‌سازی کند. یا می‌توانید ویرایشگر خودکارسازی با پایان باز بنویسید که به کاربر اجازه می‌دهد بااستفاده از همه بلوک‌های ساختمانی موجود در Automation API، خودکارسازی‌های پیچیده بسازد.

ایجاد و مدیریت خودکارسازی‌ها

برای ایجاد و مدیریت خودکارسازی‌ها در Android:

  1. همه انواع دستگاه‌ها و ویژگی‌های ارجاع‌شده توسط خودکارسازی‌هایتان را در FactoryRegistry که درطول مقداردهی اولیه کیت توسعه نرم‌افزار به HomeConfig منتقل شده است ثبت کنید. برای جزئیات ثبت، به راه‌اندازی اولیه خانه در Android مراجعه کنید.
  2. DraftAutomation (BaseAutomation) خود را بااستفاده از automation() DSL بسازید و روش‌های استاندارد HasAutomations را در شیء Structure فراخوانی کنید:
    • برای ایجاد خودکارسازی در ساختمان، createAutomation() را فراخوانی کنید.
    • برای فهرست کردن یا بازیابی خودکارسازی‌های ایجادشده توسط برنامه‌تان در ساختمان، automations() را فراخوانی کنید.
    • برای به‌روزرسانی فراداده یا جایگزین کردن automationGraph، update() را در نمونه Automation فراخوانی کنید.
    • برای برداشتن خودکارسازی با شناسه، deleteAutomation() را فراخوانی کنید.
val draft = automation {
  name = "Turn on light"
  description = "Turn on light2 when light1 turns on."
  sequential {
    val starterNode = starter<_>(light1, OnOffLightDevice, OnOff)
    condition { expression = starterNode.onOff equals true }
    action(light2, OnOffLightDevice) { command(OnOff.on()) }
  }
}

val createdAutomation = structure.createAutomation(draft)

برای مشاهده نحو کامل DSL و نمونه‌های کد CRUD، به ساخت خودکارسازی در Android مراجعه کنید.

پیشنهادهای خودکارسازی

   در برنامه نمونه برای Android پیاده‌سازی شده است   

Home API می‌تواند براساس عواملی مثل نوع دستگاه‌های موجود در فضا، خودکارسازی‌هایی را برای Structure پیشنهاد دهد.

پیشنهادهای خودکارسازی با کلاس AutomationSuggestion نشان داده می‌شود.

میانای Structure شامل میانای HasSuggestions است که تابع suggestions() را ارائه می‌دهد و مجموعه‌ای از پیشنهادهای خودکارسازی را برمی‌گرداند.

روش‌های likeSuggestion() و dislikeSuggestion() برای اتصال به کنترل‌های میانای کاربر و درنظر گرفته شده‌اند که کاربر می‌تواند برای ارائه بازخورد روی آن‌ها تک‌ضرب بزند.

روش سوم، clearSuggestionFeedback()، به کاربر اجازه می‌دهد بازخورد خود را برای خودکارسازی پیشنهادی بردارد.

بازخورد کاربر بر پیشنهادهای آینده تأثیر می‌گذارد.

این مثال نشان می‌دهد که چگونه می‌توان پیشنهادهای خودکارسازی دردسترس را برای یک Structure بازیابی کرد، شناسه پیشنهاد را استخراج کرد، و بازخورد کاربر را بااستفاده از likeSuggestion()، clearSuggestionFeedback()، و dislikeSuggestion() ثبت کرد.

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.home.Structure
import kotlinx.coroutines.launch

class AutomationSuggestionsViewModel(private val structure: Structure) : ViewModel() {

  fun loadAndGiveFeedback() {
    viewModelScope.launch {
      // 1. Fetch suggestions from structure
      val suggestions = structure.suggestions()
      val firstSuggestion = suggestions.firstOrNull() ?: return@launch

      // Extract string suggestion ID
      val suggestionId: String = firstSuggestion.id.id

      // 2. Like the suggestion (thumbs up)
      val liked = structure.likeSuggestion(suggestionId)

      // 3. Clear previous feedback if the user toggled it off
      if (liked) {
        structure.clearSuggestionFeedback(suggestionId)
      }

      // 4. Dislike the suggestion (thumbs down)
      structure.dislikeSuggestion(suggestionId)
    }
  }
}

پارامترهای فرمان پویا

پارامترهای فرمان پویا به توسعه‌دهندگان اجازه می‌دهد پارامترهای کنشی بسازند که به‌جای تکیه صرف بر مقادیر ثابت و ایستا، به‌طور پویا در زمان اجرا حل‌وفصل می‌شوند. این کار دو قابلیت اصلی را فعال می‌کند:

  • ارجاعاتی که مقدار یک ویژگی را از یک آغازگر (مانند بار داده رویداد) یا گره خواننده حالت، یا از متغیرهای محلی اعلام‌شده در جریان خودکارسازی منتقل می‌کنند.
  • عبارت‌هایی که مقادیر پویای زمان اجرا (مانند ویژگی رویداد یا مقدار وضعیت) را ضبط می‌کنند و مقدار پویا را مستقیماً به پارامتر فرمان منتقل می‌کنند.

کاربرد

یک سوئیچ چرخشی فیزیکی را که رویداد چندفشاری ارسال می‌کند به یک چراغ با نور قابل‌تنظیم متصل کنید. تعداد کلیک‌ها مقدار پویایی است که در زمان اجرا به فرمان مرحله LevelControl منتقل می‌شود.

نحوه عملکرد پارامترهای پویا

در Automation DSL در Android، پارامترهای فرمان نمونه‌های Expression یا Reference را مستقیماً به‌جای مقادیر ثابت ایستا می‌پذیرند. ‫DSL این موارد را هنگام ساختن خودکارسازی در تعاریف Parameter کپسوله‌سازی می‌کند.

قوانین اعتبارسنجی

پارامترهای فرمان پویا از این محدودیت‌های اعتبارسنجی پیروی می‌کنند:

  • پارامترهای پویا درطول اکتشاف ازنظر ساختاری معتبر فرض می‌شوند زیرا میاناهای برنامه‌سازی کاربردی اکتشاف فقط محدودیت‌های مقدار واقعی را برای استدلال‌های ایستا ارزیابی می‌کنند.
  • گره‌های مرجع یا عبارت باید در نمودار خودکارسازی در بالادست ظاهر شوند پیش‌از اینکه در کنش فرمان پایین‌دست به آن‌ها ارجاع داده شود.

استفاده از پارامترهای فرمان پویا در Android

عبارت‌های پویا را مستقیماً به پارامترهای فرمان ارسال کنید:

import com.google.home.automation.action
import com.google.home.automation.automation
import com.google.home.automation.fieldSelect
import com.google.home.automation.sequential
import com.google.home.automation.starter
import com.google.home.matter.standard.DimmableLightDevice
import com.google.home.matter.standard.DimmerSwitchDevice
import com.google.home.matter.standard.LevelControl
import com.google.home.matter.standard.LevelControlTrait.StepModeEnum
import com.google.home.matter.standard.Switch

val keypressAutomation = automation {
  name = "Dynamic command parameters example"
  description = "Pass starter event field directly to command"
  sequential {
    val dimmerStarter = starter(
      dimmerSwitch,
      DimmerSwitchDevice,
      Switch.MultiPressOngoingEvent,
    )

    val clickCountExpr = fieldSelect<Switch.MultiPressOngoingEvent, UInt>(
      dimmerStarter,
      Switch.MultiPressOngoingEvent.EventFields.currentNumberOfPressesCounted,
    )

    action(dimmableLight, DimmableLightDevice) {
      command(
        LevelControl.step(
          stepMode = StepModeEnum.Up,
          stepSize = clickCountExpr,
        )
      )
    }
  }
}

یا اینکه عبارتی را به تعریف متغیر محلی اختصاص دهید و بعداً در جریان به متغیر ارجاع دهید:

import com.google.home.automation.action
import com.google.home.automation.automation
import com.google.home.automation.fieldSelect
import com.google.home.automation.sequential
import com.google.home.automation.starter
import com.google.home.automation.variable
import com.google.home.matter.standard.DimmableLightDevice
import com.google.home.matter.standard.DimmerSwitchDevice
import com.google.home.matter.standard.LevelControl
import com.google.home.matter.standard.LevelControlTrait.StepModeEnum
import com.google.home.matter.standard.Switch

val myAutomationWithVariable = automation {
  name = "Dynamic command parameters with variables"
  description = "Declare a variable, assign value, and pass reference"
  sequential {
    val dimmerStarter = starter(
      dimmerSwitch,
      DimmerSwitchDevice,
      Switch.MultiPressOngoingEvent,
    )

    val clickCountExpr = fieldSelect<Switch.MultiPressOngoingEvent, UInt>(
      dimmerStarter,
      Switch.MultiPressOngoingEvent.EventFields.currentNumberOfPressesCounted,
    )

    val clickCountVar = variable<UInt>()
    clickCountVar.assign(clickCountExpr)

    action(dimmableLight, DimmableLightDevice) {
      command(
        LevelControl.step(
          stepMode = StepModeEnum.Up,
          stepSize = clickCountVar,
        )
      )
    }
  }
}

محدودیت‌های نوع

مطمئن شوید که انواع متغیرها و عبارت‌ها با تعریف نوع طرح‌واره Matter موردنیاز پارامتر فرمان گیرنده (مانند UShort، UByte، یا UInt8) مطابقت داشته باشند.

محدودیت‌های منبع

محدودیت‌های زیر برای خودکارسازی‌ها در Home API اعمال می‌شود:

جدول: محدودیت‌های منبع Automation API
متریک حد
حداکثر تعداد خودکارسازی‌ها برای هر ساختمان ۶۴
حداکثر تعداد گره‌ها در هر خودکارسازی 128
حداکثر تعداد گره‌های عبارت برای هر خودکارسازی ۶۴
حداکثر تعداد نمونه‌های خودکارسازی برای هر ساختمان 1024
حداکثر تعداد نمونه‌های خودکارسازی برای هر توسعه‌دهنده در هر ساختمان ۶۴
حداکثر تعداد اجراها برای هر ساختار در روز 1024
حداکثر تعداد اجراها برای هر توسعه‌دهنده در هر ساختار در روز 128