از 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 حذف میشود. ورودی تاریخچه اتوماسیون، از جمله automation_id ، در تب Activity Google Home app (GHA) باقی میماند.
ویژگیهای صفت را در یک عمل تنظیم کنید
برای تنظیم مقدار یک ویژگی صفت:
- یک گره
updateدرون یک گرهactionایجاد کنید، و ویژگی مربوطه را به عنوان آرگومان به گرهupdateارسال کنید:action(deviceReference, deviceType) { update(trait) { } } - درون گره
update، برای اصلاح هر ویژگی، از یک تابع mutator استفاده کنید و مقدار جدید را به آن منتقل کنید. برای تشکیل نام تابع mutator:- نام ویژگی را با حروف بزرگ بنویسید
- آن را با کلمه
setپیشوند کنید.
defaultMoveRate، از یک تابع mutator به نامsetDefaultMoveRateاستفاده میکنید.
توجه داشته باشید که یک گره update میتواند چندین تابع تغییردهنده داشته باشد. در اینجا مثالی آورده شده است که در آن دو ویژگی بهروزرسانی میشوند:
typealias FanDeviceType = Matter.FanDeviceType
typealias FanControlTrait = Matter.FanControlTrait
action(fan, FanDeviceType.self) {
update(FanControlTrait.self) {
$0.setFanMode(.on)
}
}