از راهنمای زیر برای درک چگونگی استفاده از گرههای مختلف اتوماسیون DSL برای ساخت یک اتوماسیون استفاده کنید.
تمام DSL اتوماسیون در یک گره automation واحد قرار میگیرد. گره automation مرز بین متن زبان Swift بیرونی و متن DSL تعبیهشده را تشکیل میدهد.
جریان متوالی
جریان ترتیبی، نوع پیشفرض جریان اتوماسیون است.
در اینجا یک الگوی DSL اتوماسیون بسیار ابتدایی وجود دارد که از یک جریان ترتیبی متشکل از یک شروعکننده، یک شرط و یک عمل استفاده میکند:
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
starter(...)
condition {...}
action {...}
}
این را میتوان با اضافه کردن گرههای اضافی اصلاح کرد.
استارتر
گرههای آغازگر، شرایط اولیهای را که یک اتوماسیون را فعال میکنند، تعریف میکنند. برای مثال، تغییر در وضعیت یا مقدار. یک اتوماسیون باید حداقل یک آغازگر داشته باشد، در غیر این صورت اعتبارسنجی آن با شکست مواجه میشود. برای اضافه کردن بیش از یک آغازگر به یک اتوماسیون، باید از یک گره select (select node) استفاده کنید.
شروع کننده بر اساس ویژگی صفت
هنگام اعلام یک گره آغازگر که مبتنی بر یک ویژگی trait است، موارد زیر را مشخص کنید:
- دستگاه
- نوع دستگاهی که ویژگی به آن تعلق دارد
- صفت
starter(
thermostat,
Matter.TemperatureSensorDeviceType.self,
Matter.TemperatureMeasurementTrait.self
)
پارامتر نوع دستگاه الزامی است زیرا به شما امکان میدهد مشخص کنید کدام نوع دستگاه در یک دستگاه، آدرسدهی خودکار را انجام میدهد. برای مثال، یک دستگاه ممکن است از یک FanDeviceType و یک HeatingCoolingUnitDeviceType تشکیل شده باشد که هر دو حاوی ویژگی OnOffTrait هستند. با مشخص کردن نوع دستگاه، هیچ ابهامی در مورد اینکه کدام بخش از دستگاه، خودکارسازی را آغاز میکند، وجود ندارد.
شروع کننده بر اساس رویداد
هنگام تعریف یک گره آغازگر که مبتنی بر یک رویداد است، موارد زیر را مشخص کنید:
- دستگاه
- نوع دستگاهی که ویژگی به آن تعلق دارد
- رویداد
starter(
doorbell,
Google.GoogleDoorbellDeviceType.self,
Google.DoorbellPressTrait.DoorbellPressedEvent
)
شروع کننده بر اساس یک ساختار و رویداد، با پارامترها
برخی رویدادها میتوانند پارامترهایی داشته باشند، بنابراین این پارامترها نیز باید در آغازگر گنجانده شوند.
برای مثال، این شروعکننده از ScheduledEvent مربوط به TimeTrait برای فعال کردن اتوماسیون در ساعت ۷:۰۰ صبح استفاده میکند:
typealias TimeTrait = Google.TimeTrait
let earlyMorning = starter(
structure,
TimeTrait.ScheduledEvent.self
) {
TimeTrait.ScheduledEvent.clockTime(TimeOfDay(hours: 7, minutes: 0))
}
استارت دستی
استارتر دستی نوع خاصی از استارتر است که به کاربر اجازه میدهد اتوماسیون را به صورت دستی اجرا کند.
هنگام اعلام استارت دستی:
- نوع یا ویژگی دستگاه را مشخص نکنید.
- یک عنصر رابط کاربری ارائه دهید که
Automation.execute()را فراخوانی کند.
هنگام قرار دادن یک استارتر دستی در یک جریان select به همراه یک استارتر دیگر، استارتر دستی بر استارتر دیگر غلبه میکند:
select {
manualStarter()
starter(
thermostat,
Matter.TemperatureSensorDeviceType.self,
Matter.TemperatureMeasurementTrait.self
)
}
توجه داشته باشید که هر گره condition که پس از یک شروعکننده دستی قرار گیرد، ارزیابی خواهد شد و بسته به عبارت condition ، میتواند اجرای اتوماسیون را مسدود کند.
یک راه برای ساختاردهی اتوماسیون به گونهای که گرههای condition ، اتوماسیونی را که با یک استارتر دستی فعال شده است، مسدود نکنند، قرار دادن استارتر دیگر در یک جریان ترتیبی جداگانه به همراه condition آن است:
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
select {
sequential {
starter(...)
condition {...}
}
sequential {
manualStarter()
}
}
action {...}
}
ارجاع به مقدار یک ویژگی
برای استفاده از مقدار یک ویژگی در یک عبارت، از سینتکس زیر استفاده کنید.
با یک stateReader :
typealias TimeTrait = Google.TimeTrait
let time = stateReader(structure, TimeTrait.self)
time
let currTime = time.currentTime
با یک starter :
typealias LaundryWasherDeviceType = Matter.LaundryWasherDeviceType
typealias OnOffTrait = Google.OnOffTrait
let starterNode = starter(device1, LaundryWasherDeviceType.self, OnOffTrait.self)
starterNode
condition {
starterNode.onOff.equals(true)
}
گرهها و عبارات شرطی
یک گره شرط، نشاندهندهی یک نقطهی تصمیمگیری است که تعیین میکند آیا اتوماسیون ادامه پیدا میکند یا خیر. یک اتوماسیون میتواند چندین گره condition داشته باشد. اگر عبارت هر گره condition ، false ارزیابی شود، اجرای کل اتوماسیون پایان مییابد.
در یک گره condition ، میتوانید چندین معیار شرط را با استفاده از عملگرهای مختلف ترکیب کنید، تا زمانی که عبارت به یک مقدار بولی واحد ارزیابی شود. اگر مقدار حاصل true باشد، شرط برآورده شده و اتوماسیون اجرای گره بعدی را ادامه میدهد. اگر false باشد، اتوماسیون در آن نقطه اجرا را متوقف میکند.
عبارات مشابه عبارات در سوئیفت ساخته میشوند و ممکن است شامل مقادیر اولیه مانند اعداد، کاراکترها، رشتهها و مقادیر بولی و همچنین مقادیر شمارشی باشند. گروهبندی زیرعبارات با پرانتز به شما امکان میدهد ترتیب ارزیابی آنها را کنترل کنید.
در اینجا مثالی از condition که چندین زیرعبارت را در یک عبارت واحد ترکیب میکند، آورده شده است:
condition {
let exp1 = starterNode.lockState.equals(.unlocked)
let exp2 = stateReaderNode.lockState.equals(true)
let exp3 = occupancySensingDevice.occupied.notEquals(0)
(exp1.and(exp2)).or(exp3)
}
شما میتوانید مقدار یک ویژگی (trait) که از طریق یک آغازگر (starter) قابل دسترسی است را ارجاع دهید:
typealias OnOffTrait = Matter.OnOffTrait
let starterNode = starter(device, OnOffTrait.self)
starterNode
condition {
starterNode.onOff.equals(true)
}
val starterNode = starter<_>(device, OnOff)
condition() { expression = starterNode.onOff equals true }
stateReader
راه دیگر برای ارجاع به مقادیر ویژگی trait در یک گره condition ، استفاده از گره stateReader است.
برای انجام این کار، ابتدا مقدار ویژگی trait را در یک گره stateReader ثبت کنید. یک stateReader structure و trait را به عنوان آرگومان دریافت میکند:
typealias ActivatedCarbonFilterMonitoringTrait = Matter.ActivatedCarbonFilterMonitoringTrait
let filterMonitoringState = stateReader(structure, ActivatedCarbonFilterMonitoringTrait.self)
سپس در گره condition به stateReader ارجاع دهید:
condition {
filterMonitoringState.changeIndication.equals(.warning)
}
با استفاده از عملگرهای مقایسهای و منطقی ، میتوان از چندین stateReaders در یک گره condition استفاده کرد:
typealias ArmDisarm = Google.ArmDisarmTrait
typealias DoorLockDevice = Matter.DoorLockDeviceType
typealias DoorLock = Matter.DoorLockTrait
let armState = stateReader(doorLock, DoorLockDevice.self, ArmDisarm )
let doorLockState = stateReader(doorLock, DoorLockDevice.self, DoorLock)
armState
doorLockState
condition {
let exp1 = armState.armState
let exp2 = doorLockState.lockState
exp1.and(exp2)
}
مدت زمان شرایط
علاوه بر یک عبارت بولی در یک شرط، میتوانید یک بازه زمانی مشخص کنید که در طی آن عبارت باید درست باشد تا اتوماسیون اجرا شود. به عنوان مثال، میتوانید شرطی تعریف کنید که فقط در صورتی اجرا شود که چراغی به مدت ده دقیقه روشن بوده باشد.
condition(for: .seconds(600)) {
lightStateReader.onOff.equals(true)
}
مدت زمان میتواند از یک تا 30 دقیقه متغیر باشد.
گرههای عمل
گره action جایی است که کار اتوماسیون در آن انجام میشود. در این مثال، action دستور broadcast() مربوط به AssistantBroadcastTrait را فراخوانی میکند:
action(speaker, SpeakerDeviceType.self) {
Google.AssistantBroadcastTrait.broadcast(msg: "Oven Cycle Complete")
}