از Automation DSL میتوان برای ایجاد خودکارسازیهایی استفاده کرد که پیچیدهتر از موارد بحثشده در راهنمای DSL - خودکارسازیهای پایه در iOS هستند.
متوالی با چند کنش
خودکارسازی میتواند بیشاز یک کار انجام دهد. برای مثال، بهجای یک گره action، میتوانید چند گره action داشته باشید که بهصورت متوالی اجرا میشوند:
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
starter(...)
condition {...}
action {...}
action {...}
action {...}
}
متوالی با چند کنش موازی
اگر چند گره action را در یک گره parallel قرار دهید، کنشها بهطور همزمان اجرا میشوند.
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
starter(...)
condition {...}
parallel {
action {...}
action {...}
action {...}
}
}
اگر action گره در گره sequential وجود داشته باشد که بعداز گره parallel قرار گرفته باشد،
این گرهها تا زمانی که اجرای همه گرههای موجود در گره 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.
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.")
}
}
اجرای کنشهای مختلف براساس یک شرط
برای اجرای یک مجموعه کنش درصورت درست بودن شرط و مجموعه کنشهای جایگزین درصورت نادرست بودن آن، بلوک اختیاری .orElse { ... } را بعداز ifThen(...) { ... } زنجیر کنید:
// 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
را میگیرد که نشاندهنده مدت مکث قبلاز ادامه اجرا است. مدت توقف میتواند از پنج ثانیه تا ۲۴ ساعت باشد.
برای مثال، برای چهار بار روشن و خاموش کردن چراغ با مکث پنج ثانیهای بین هر بار روشن و خاموش کردن:
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
استفاده کنید که نشاندهنده مدت زمان انتظار قبلاز پاسخ دادن به راهاندازهای بعدی است.
مدتزمان توقف ممکن است کوتاه و در حد پنج ثانیه یا طولانی و تا ۲۴ ساعت باشد.
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.
تنظیم مشخصههای ویژگی در کنش
برای تنظیم مقدار مشخصه ویژگی:
- یک گره
updateدر گرهactionایجاد کنید، و ویژگی مربوطه را بهعنوان آرگومان به گرهupdateاضافه کنید:action(deviceReference, deviceType) { update(trait) { } } - در گره
update، برای هر مشخصهای که باید اصلاح شود، از تابع جهشدهنده استفاده کنید و مقدار جدید را به آن منتقل کنید. برای تشکیل نام تابع تغییردهنده:- نام مشخصه را با حروف بزرگ بنویسید
- پیشوند آن را با کلمه
setشروع کنید.
defaultMoveRate، از تابع جهشدهندهای بهنامsetDefaultMoveRateاستفاده میکنید.
توجه داشته باشید که یک گره update میتواند چندین تابع جهشدهنده داشته باشد. در اینجا مثالی آورده شده است که در آن دو مشخصه بهروزرسانی شدهاند:
typealias FanDeviceType = Matter.FanDeviceType
typealias FanControlTrait = Matter.FanControlTrait
action(fan, FanDeviceType.self) {
update(FanControlTrait.self) {
$0.setFanMode(.on)
}
}