คู่มือ DSL ของ iOS

ใช้คําแนะนําต่อไปนี้เพื่อทำความเข้าใจว่าโหนด Automation DSL ต่างๆ อาจนําไปใช้สร้างการทำงานอัตโนมัติได้อย่างไร

DSL การทำงานอัตโนมัติทั้งหมดจะอยู่ในโหนด automation โหนดเดียว โหนด automation จะกำหนดขอบเขตระหว่างบริบทภาษา Swift ด้านนอกกับบริบท DSL ที่ฝัง

ขั้นตอนตามลําดับ

โฟลว์ตามลําดับเป็นประเภทเริ่มต้นของโฟลว์การทำงานอัตโนมัติ

ตัวอย่าง DSL แบบตามลำดับ

ต่อไปนี้คือเทมเพลต Automation DSL พื้นฐานที่สุดที่ใช้ลำดับการทำงานแบบต่อเนื่องซึ่งประกอบด้วยเงื่อนไขเริ่มต้น เงื่อนไข และการดำเนินการ

import GoogleHomeSDK
import GoogleHomeTypes

automation (
...
) {
  starter(...)
  condition {...}
  action {...}
}

ซึ่งสามารถปรับแต่งได้โดยการเพิ่มโหนดเพิ่มเติม

Starter

โหนดเงื่อนไขเริ่มต้นจะกำหนดสถานการณ์เริ่มต้นที่เปิดใช้งานการทำงานอัตโนมัติ เช่น การเปลี่ยนแปลงสถานะหรือค่า การทำงานอัตโนมัติต้องมีเงื่อนไขเริ่มต้นอย่างน้อย 1 รายการ มิฉะนั้นจะไม่สามารถตรวจสอบได้ หากต้องการเพิ่มเงื่อนไขเริ่มต้นมากกว่า 1 รายการในการทำงานอัตโนมัติ คุณต้องใช้โหนด select

เงื่อนไขเริ่มต้นตามแอตทริบิวต์ลักษณะ

เมื่อประกาศโหนดเริ่มต้นที่อิงตามแอตทริบิวต์ลักษณะ ให้ระบุข้อมูลต่อไปนี้

  • อุปกรณ์
  • ประเภทอุปกรณ์ที่ลักษณะนิสัยนั้นอยู่
  • ลักษณะ
starter(
  thermostat,
  Matter.TemperatureSensorDeviceType.self,
  Matter.TemperatureMeasurementTrait.self
)

ต้องระบุพารามิเตอร์ประเภทอุปกรณ์เนื่องจากจะช่วยให้คุณระบุประเภทอุปกรณ์ภายในอุปกรณ์ที่ระบบอัตโนมัติจะจัดการ ตัวอย่างเช่น อุปกรณ์อาจประกอบด้วย FanDeviceType และ HeatingCoolingUnitDeviceType ซึ่งทั้ง 2 รายการมีคุณลักษณะ OnOffTrait การระบุประเภทอุปกรณ์จะทำให้ไม่เกิดความสับสนว่าส่วนใดของอุปกรณ์ที่ทริกเกอร์การทำงานอัตโนมัติ

เงื่อนไขเริ่มต้นตามเหตุการณ์

เมื่อประกาศโหนดเงื่อนไขเริ่มต้นที่อิงตามเหตุการณ์ ให้ระบุข้อมูลต่อไปนี้

  • อุปกรณ์
  • ประเภทอุปกรณ์ที่ลักษณะนิสัยนั้นอยู่
  • กิจกรรม
starter(
  doorbell,
  Google.GoogleDoorbellDeviceType.self,
  Google.DoorbellPressTrait.DoorbellPressedEvent
)

เงื่อนไขเริ่มต้นที่อิงตามโครงสร้างและเหตุการณ์พร้อมพารามิเตอร์

เหตุการณ์บางรายการอาจมีพารามิเตอร์ ดังนั้นจึงต้องรวมพารามิเตอร์เหล่านี้ไว้ในเงื่อนไขเริ่มต้นด้วย

ตัวอย่างเช่นเงื่อนไขเริ่มต้นนี้ใช้ ScheduledEvent ของ TimeTrait เพื่อเปิดใช้งานการทำงานอัตโนมัติเวลา 07:00 น.

typealias TimeTrait = Google.TimeTrait

let earlyMorning = starter(
  structure,
  TimeTrait.ScheduledEvent.self
) {
  TimeTrait.ScheduledEvent.clockTime(TimeOfDay(hours: 7, minutes: 0))
}

เงื่อนไขเริ่มต้นด้วยตนเอง

เงื่อนไขเริ่มต้นด้วยตนเองคือเงื่อนไขเริ่มต้นประเภทพิเศษที่อนุญาตให้ผู้ใช้เรียกใช้การทำงานอัตโนมัติด้วยตนเอง

เมื่อประกาศเงื่อนไขเริ่มต้นด้วยตนเอง

  • อย่าระบุลักษณะหรือประเภทอุปกรณ์
  • ระบุองค์ประกอบ UI ที่เรียกใช้ 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 การทำงานอัตโนมัติจะหยุดลง ณ จุดนั้น

นิพจน์มีรูปแบบคล้ายกับนิพจน์ใน Swift และอาจมีค่าพื้นฐาน เช่น ตัวเลข อักขระ สตริง และบูลีน รวมถึงค่า Enum การจัดกลุ่มนิพจน์ย่อยด้วยวงเล็บช่วยให้คุณควบคุมลําดับการประเมินนิพจน์ย่อยได้

ต่อไปนี้คือตัวอย่าง 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)
}

คุณสามารถอ้างอิงค่าของลักษณะที่เข้าถึงผ่านเงื่อนไขเริ่มต้นได้ดังนี้

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

อีกวิธีในการอ้างอิงค่าแอตทริบิวต์ลักษณะในโหนด condition คือการใช้โหนด stateReader

โดยให้บันทึกค่าแอตทริบิวต์ลักษณะในโหนด stateReader ก่อน stateReader ใช้ structure และลักษณะเป็นอาร์กิวเมนต์

typealias ActivatedCarbonFilterMonitoringTrait = Matter.ActivatedCarbonFilterMonitoringTrait

let filterMonitoringState = stateReader(structure, ActivatedCarbonFilterMonitoringTrait.self)

จากนั้นอ้างอิง stateReader ในโหนด condition ดังนี้

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)
}

ระยะเวลาของเงื่อนไข

นอกจากนิพจน์บูลีนในเงื่อนไขแล้ว คุณยังระบุกรอบเวลาได้ในระหว่างที่นิพจน์ต้องเป็นจริงจึงจะทํางานอัตโนมัติได้ เช่น คุณอาจกำหนดเงื่อนไขที่จะทริกเกอร์เฉพาะในกรณีที่ไฟเปิดอยู่นาน 10 นาที

condition(for: .seconds(600)) {
lightStateReader.onOff.equals(true)
}

ระยะเวลามีตั้งแต่ 1 ถึง 30 นาที

โหนดการดำเนินการ

นอตการดำเนินการคือที่ที่การทำงานอัตโนมัติเกิดขึ้น ในตัวอย่างนี้ การดำเนินการจะเรียกใช้คำสั่ง broadcast() ของ AssistantBroadcastTrait

action(speaker, SpeakerDeviceType.self) {
  Google.AssistantBroadcastTrait.broadcast(msg: "Oven Cycle Complete")
}