คุณสามารถใช้ Automation DSL เพื่อสร้างการทำงานอัตโนมัติที่ซับซ้อนกว่า ที่กล่าวถึงใน คู่มือ DSL - การทำงานอัตโนมัติพื้นฐานใน iOS
การทำงานตามลำดับที่มีการดำเนินการหลายอย่าง
การทำงานอัตโนมัติสามารถทำได้มากกว่า 1 อย่าง เช่น คุณสามารถมีโหนด 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(...) { ... } ที่ไม่บังคับอย่างน้อย 1 บล็อกเพื่อประเมินเงื่อนไขหลายรายการตามลำดับ ระบบจะดำเนินการสาขาแรกที่เงื่อนไขประเมินเป็น 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
ที่แสดงระยะเวลาที่จะหยุดชั่วคราวก่อนดำเนินการต่อ ระยะเวลาหยุดชั่วคราวอาจสั้นเพียง 5 วินาทีหรือนานถึง 24 ชั่วโมง
ตัวอย่างเช่น หากต้องการสลับไฟ 4 ครั้งโดยหยุดชั่วคราว 5 วินาทีระหว่างการสลับแต่ละครั้ง ให้ทำดังนี้
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 ที่ทริกเกอร์โดยการตรวจจับการเคลื่อนไหว
และหากคุณระบุระยะเวลาการระงับทริกเกอร์เป็น 5 นาที เมื่อ
starter ทริกเกอร์แล้ว จะไม่ทริกเกอร์อีกครั้งในอีก 5 นาทีข้างหน้า ซึ่งจะป้องกันไม่ให้การทำงานอัตโนมัติทริกเกอร์ซ้ำๆ อย่างรวดเร็ว
หากต้องการใช้การระงับทริกเกอร์กับการทำงานอัตโนมัติ ให้ใช้
suppress(for:)
คีย์เวิร์ดพร้อม
Duration
อาร์กิวเมนต์ที่แสดงระยะเวลาที่จะรอการตอบสนองต่อทริกเกอร์ที่ตามมา
ระยะเวลาการระงับอาจสั้นเพียง 5 วินาทีหรือนานถึง 24 ชั่วโมง
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โดยใส่ลักษณะที่เกี่ยวข้องเป็นอาร์กิวเมนต์ของโหนดupdateaction(deviceReference, deviceType) { update(trait) { } } - ภายในโหนด
updateให้ใช้ฟังก์ชัน Mutator สำหรับแต่ละแอตทริบิวต์ที่จะแก้ไข และส่งค่าใหม่ไปยังฟังก์ชันดังกล่าว วิธีสร้างชื่อฟังก์ชัน Mutator- ขึ้นต้นชื่อแอตทริบิวต์ด้วยตัวพิมพ์ใหญ่
- นำหน้าด้วยคำว่า
set
defaultMoveRate, คุณจะต้องใช้ฟังก์ชัน Mutator ที่ชื่อว่าsetDefaultMoveRate.
โปรดทราบว่าโหนด update มีฟังก์ชัน Mutator ได้หลายฟังก์ชัน ตัวอย่างต่อไปนี้แสดงการอัปเดตแอตทริบิวต์ 2 รายการ
typealias FanDeviceType = Matter.FanDeviceType
typealias FanControlTrait = Matter.FanControlTrait
action(fan, FanDeviceType.self) {
update(FanControlTrait.self) {
$0.setFanMode(.on)
}
}