مفاهیم DSL در Android

این مروری بر مفاهیم اساسی Automation DSL در Android است.

قطعات خودکارسازی

خودکارسازی از مؤلفه‌های اصلی زیر تشکیل شده است که معمولاً به‌این ترتیب ارزیابی می‌شوند:

  1. آغازگر — شرایط اولیه‌ای را که خودکارسازی را فعال می‌کند تعریف می‌کند، مثل تغییر در یک ویژگی. خودکارسازی باید آغازگر داشته باشد.
  2. شرط — هرگونه محدودیت اضافی برای ارزیابی پس‌از فعال شدن خودکارسازی. عبارت موجود در «شرط» باید به true ارزیابی شود تا کنش‌های خودکارسازی ادامه یابد.
  3. کنش — فرمان‌ها یا به‌روزرسانی‌های وضعیتی که وقتی همه شرایط برآورده شده باشند انجام می‌شوند.

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

  1. آغازگر — تلویزیون روشن شد که تغییری در وضعیت ویژگی تلویزیون است.
  2. شرط— زمان فعلی خانه‌ای که تلویزیون در آن قرار دارد ارزیابی می‌شود.
  3. کنش — چراغ‌های اتاقی که تلویزیون در آن قرار دارد کم‌نور می‌شود.

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

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

گره‌ها

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

جدول: انواع گره‌های خودکارسازی
Node نوع گره پیاده‌سازی Kotlin شرح
Starter رفتاری StarterNodeDsl وقتی وضعیت مشخصه‌ای (هر ویژگی‌ای) تغییر می‌کند، خودکارسازی را شروع می‌کند.
StateReader رفتاری StateReaderNodeDsl مشخصه ویژگی را می‌خواند و به شما امکان می‌دهد مقدار آن را برای استفاده در گره‌های شرطی ضبط کنید.
کنش رفتاری ActionNodeDsl فرمان(های) مشخصه را فراخوانی می‌کند.
متوالی جریان اجرا SequentialFlow گره‌های کنش تودرتو را به‌ترتیب اجرا می‌کند. این رفتار اجرای پیش‌فرض است.
موازی جریان اجرا ParallelFlow گره‌های کنش تودرتو را به‌صورت موازی اجرا می‌کند.
وضعیت جریان اجرا ConditionNodeDsl جریان اجرا را به‌طور مشروط براساس ارزیابی‌های عبارات منطقی تغییر دهید. شرایط ممکن است با یک آغازگر مرتبط باشد (شرایط خاص آغازگر) یا جهانی باشد (برای همه آغازگرها اعمال شود).
انتخاب کردن جریان اجرا SelectFlow امکان استفاده از بیش‌از یک آغازگر برای فعال کردن خودکارسازی را فراهم می‌کند.
IfFlow جریان اجرا IfFlowDsl براساس اینکه کدام شرط (درصورت وجود) درست ارزیابی شود، حداکثر یک کنش (یا شاخه) را اجرا می‌کند (مشابه عبارت if-then-else).
بیان مقدار Expression ممکن است مقدار مشخصه یک ویژگی، یک ثابت، یا یک مقدار دقیق باشد، و باید به یک فهرست، عدد، بولی، یا رشته ارزیابی شود.

گره‌های رفتاری

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

گره‌های رفتاری معمولاً به ویژگی‌های دستگاه و وضعیت ویژگی خروجی برای استفاده به‌عنوان ورودی در گره‌های دیگر مرتبط هستند.

گره‌های جریان اجرا

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

برای مثال، یک جریان متوالی ممکن است حاوی گره‌هایی باشد که به‌ترتیب متوالی اجرا می‌شوند. معمولاً این گره‌ها عبارت‌اند از آغازگر، شرط، و کنش.

جریان‌های اجرای متوالی
شکل ۱: جریان خودکارسازی متوالی

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

جریان‌های اجرای موازی
شکل ۲: جریان خودکارسازی موازی

نوع دیگری از جریان اجرا جریان شرطی است که می‌تواند جریان اجرا را براساس ارزیابی یک عبارت تغییر دهد.

برای مثال، شاید خودکارسازی‌ای داشته باشید که کنشی را براساس اینکه شب است یا نه انجام می‌دهد. گره شرطی زمان روز را بررسی می‌کند، سپس مسیر اجرای مناسب را براساس آن ارزیابی دنبال می‌کند.

جریان شرط
شکل ۳: جریان شرط

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

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

انتخاب جریان
شکل ۴: انتخاب جریان

جریان if-then-else (IfFlow) امکان اجرای شرطی شاخه‌ای را در خودکارسازی فراهم می‌کند. برخلاف گره condition که اگر شرط false باشد کل خودکارسازی را متوقف می‌کند، جریان «اگر-آنگاه-وگرنه» به‌صورت شرطی کنش‌های خاصی را وقتی شرط درست باشد اجرا می‌کند و می‌تواند به شرایط جایگزین یا کنش‌های احتیاطی برگردد یا به گره‌های بعدی در خودکارسازی ادامه دهد. برای جزئیات بیشتر، به اجرای شرطی مراجعه کنید.

جریان‌های تودرتو

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

جریان‌های اجرای تودرتو
شکل ۵: جریان‌های اجرای تودرتو

گره‌های DSL را می‌توان به روش‌های مختلفی تودرتو و ترکیب کرد تا نیازهای خاص شما را برآورده کند، مطابق با محدودیت‌های ذکرشده در جدول زیر. ستون «سازنده» به مستندات سازنده typesafe در Kotlin پیوند دارد که جزئیات آنچه را که برای استفاده در هر نوع گره مجاز است شرح می‌دهد.

جدول: نحوه ترکیب گره‌ها
Node ممکن است حاوی نوع گره و داده‌های زیر باشد باید در یکی از انواع گره‌های زیر باشد
Starter عبارت انتخاب، متوالی
ManualStarter انتخاب، متوالی
StateReader عبارت (معمولاً شامل مقدار مشخصه ویژگی) IfFlow، موازی، متوالی
کنش فرمان، نهاد، حالت چهره IfFlow, Parallel, Select, Sequential
متوالی IfFlow, Parallel, Select, Sequential
موازی کنش IfFlow، متوالی
وضعیت عبارت IfFlow، موازی، متوالی
انتخاب کردن Condition, Sequential, Starter, ManualStarter متوالی، و باید اولین گره در جریان باشد
IfFlow Action, Condition, Delay, IfFlow, Parallel, Sequential, StateReader, Suppression ترتیبی

DSL خودکارسازی

در Home API، خودکارسازی‌ها بااستفاده از Automation DSL (زبان مختص دامنه) تعریف می‌شوند. ‫Automation DSL به‌عنوان Kotlin DSL (زبان مختص دامنه) پیاده‌سازی شده است، از سازندگان ایمنی تایپی Kotlin استفاده می‌کند، و به‌طور خاص برای تعریف کردن الگوهای خودکارسازی طراحی شده است.

وقتی خودکارسازی کامپایل می‌شود، سازندگان ایمن ازنظر نوع Kotlin کلاس‌های داده Kotlin را تولید می‌کنند که سپس به JSON میان‌گیر پروتکل سریال‌سازی می‌شوند، که برای برقراری تماس با «سرویس‌های خودکارسازی» Google استفاده می‌شود.

«زبان خاص دامنه» (DSL) خودکارسازی فرایند ساختن خودکارسازی‌ها را ساده و کارآمد می‌کند. این میانای برنامه‌سازی کاربردی به‌طور بومی از همان مدل داده ویژگی‌های استاندارد Matter و ویژگی‌های smart home استفاده می‌کند که در Device API ارائه شده است.

Automation DSL همچنین منطق خودکارسازی را ازنظر انواع دستگاه‌های انتزاعی تعریف می‌کند، برخلاف نمونه‌های خاص دستگاه که در خانه کاربر قرار دارند. این ویژگی به توسعه‌دهنده امکان می‌دهد پارامترهای ورودی را ارائه دهد که ممکن است در زمان اجرا برای مشخص کردن نمونه‌های واقعی دستگاه و همچنین سایر مقادیر مهم پارامتر استفاده شوند.

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

مثال

در زیر نمونه‌ای از خودکارسازی برای روشن کردن دستگاه آورده شده است که بااستفاده از Automation DSL نوشته شده است:

val automation = automation {
  name = "MyFirstAutomation"
  description = "If light1 is on, turn on light2."
  isActive = true
  sequential {
    val onOffTrait = starter<_>(device1, OnOffLightDevice, OnOff)
    condition() { expression = onOffTrait.onOff equals true }
    action(device2, OnOffLightDevice) { command(OnOff.on()) }
  }
}

این خودکارسازی بسیار ساده است: وقتی device1، یعنی چراغ، روشن می‌شود (ویژگی onOff به true تغییر می‌کند)، سپس فرمان on() را برای روشن کردن device2 ارسال می‌کند.

این خودکارسازی از گره sequential استفاده می‌کند که نشان می‌دهد گره‌های آن به‌ترتیب متوالی اجرا خواهند شد.

در گره sequential، گره‌های رفتاری مانند starter، condition، و action وجود دارد. خروجی گره starter به متغیری برای استفاده در گره condition اختصاص داده شده است.