คู่มือ DSL ของ Android

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

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

โฟลว์แบบลำดับ

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

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

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


import com.google.home.automation.action
import com.google.home.automation.automation
import com.google.home.automation.condition
import com.google.home.automation.sequential
import com.google.home.automation.starter

...

automation {
  sequential {
    starter<_>(...)
    condition {...}
    action {...}
  }
}

คุณปรับแต่งได้โดยการเพิ่มโหนดเพิ่มเติม

Starter

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

การเริ่มต้นโดยอิงตามแอตทริบิวต์ลักษณะ

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

  • อุปกรณ์
  • ประเภทอุปกรณ์ที่ลักษณะนี้เป็นของ
  • ลักษณะ
starter<_>(thermostat, TemperatureSensorDevice, TemperatureMeasurement)

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

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

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

  • อุปกรณ์
  • ประเภทอุปกรณ์ที่ลักษณะนี้เป็นของ
  • กิจกรรม
starter<_>(doorBell, GoogleDoorbellDevice, DoorbellPressed)

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

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

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

val earlyMorning = starter<_>(structure, Time.ScheduledTimeEvent) {
  parameter(Time.ScheduledTimeEvent.clockTime(
    LocalTime.of(7, 0, 0, 0)))
}

Manual starter

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

เมื่อประกาศตัวเริ่มต้นด้วยตนเอง ให้ทำดังนี้

  • อย่าระบุลักษณะหรือประเภทอุปกรณ์
  • ระบุองค์ประกอบ UI ที่เรียกใช้ Automation.execute()

เมื่อวางเงื่อนไขเริ่มต้นที่กำหนดเองในโฟลว์ select พร้อมกับเงื่อนไขเริ่มต้นอื่น เงื่อนไขเริ่มต้นที่กำหนดเองจะลบล้างเงื่อนไขเริ่มต้นอื่น

select {
  manualStarter()
  starter<_>(thermostat, TemperatureSensorDevice, TemperatureMeasurement)
}

โปรดทราบว่าระบบจะประเมินconditionโหนดที่ตามหลังตัวเริ่มต้นที่กำหนดเอง และอาจบล็อกการดำเนินการของระบบอัตโนมัติ ทั้งนี้ขึ้นอยู่กับcondition นิพจน์

การแยกทริกเกอร์ที่กำหนดเองออกจากทริกเกอร์ตามเงื่อนไข

วิธีหนึ่งในการจัดโครงสร้างการทำงานอัตโนมัติเพื่อให้conditionโหนดไม่บล็อกการทำงานอัตโนมัติที่เปิดใช้งานด้วยเงื่อนไขเริ่มต้นแบบแมนนวลคือการใส่เงื่อนไขเริ่มต้นอื่นๆ ในโฟลว์แบบลำดับแยกต่างหากพร้อมกับcondition

automation_graph {
  sequential {
    select {
      sequential {
        starter<_>(...)
        condition {...}
      }
      sequential {
        manualStarter()
      }
    }
    action {...}
  }
}

อ้างอิงค่าของแอตทริบิวต์

หากต้องการใช้ค่าของแอตทริบิวต์ในนิพจน์ ให้ใช้ไวยากรณ์ต่อไปนี้

หากใช้ stateReader ให้ทำดังนี้

val time = stateReader<_>(structure, Structure, Time)
val currTime = time.currentTime

หากใช้ starter ให้ทำดังนี้

val starterNode = starter<_>(device1, LaundryWasherDevice, OnOff)
condition() {
  expression = starterNode.onOff equals true
}

โหนดและนิพจน์ของเงื่อนไข

โหนดเงื่อนไขแสดงถึงจุดตัดสินใจที่กำหนดว่าการทำงานอัตโนมัติจะดำเนินต่อไปหรือไม่ การทำงานอัตโนมัติมีโหนด condition ได้หลายโหนด หากนิพจน์ของโหนด condition ใดก็ตามประเมินเป็น false การดำเนินการของ การทำงานอัตโนมัติทั้งหมดจะสิ้นสุดลง

ภายในconditionโหนด คุณสามารถรวมเกณฑ์เงื่อนไขหลายรายการโดยใช้โอเปอเรเตอร์ต่างๆ ได้ ตราบใดที่นิพจน์ประเมินเป็นค่าบูลีนเดียว หากค่าที่ได้เป็น true แสดงว่าตรงตามเงื่อนไขและระบบจะ ดำเนินการต่อโดยเรียกใช้โหนดถัดไป หากเป็น false ระบบอัตโนมัติ จะหยุดดำเนินการ ณ จุดนั้น

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

ต่อไปนี้คือตัวอย่างของ condition ซึ่งรวมนิพจน์ย่อยหลายรายการไว้ในนิพจน์เดียว

condition() {
  val expr1 = starterNode.lockState equals DlLockState.Unlocked
  val expr2 = stateReaderNode.lockState equals true

  val expr3 = occupancySensingDevice.occupied notEquals 0
  val expr4 = timeStateReaderNode
    .currentTime
    .between(
      timeStateReaderNode.sunsetTime,
      timeStateReaderNode.sunriseTime)
  expression = (expr1 and expr2) or (expr3 and expr4)
}

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

val starterNode = starter<_>(device, OnOff)
condition() { expression = starterNode.onOff equals true }

stateReader

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

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

import com.google.home.automation.stateReader
...
val filterMonitoringState = stateReader<_>(structure, ActivatedCarbonFilterMonitoring)

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

condition() {
  expression =
    filterMonitoringState.changeIndication
      .equals(ChangeIndicationEnum.Warning)
}

การใช้โอเปอเรเตอร์เปรียบเทียบและ โอเปอเรเตอร์เชิงตรรกะ คุณอาจใช้stateReadersหลายรายการในโหนด condition ดังนี้

val armState = stateReader<_>(doorLock, DoorLockDevice, ArmDisarm )
val doorLockState = stateReader<_>(doorLock, DoorLockDevice, DoorLock)
condition() {
  expression =
    (armState.armState equals true)
    and
    (doorLockState.lockState equals true)
}

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

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

  condition {
    expression(lightStateReader.onOff == true)
    forDuration(Duration.ofMinutes(10))
  }

ระยะเวลาอาจอยู่ในช่วง 1-30 นาที

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

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

action(device, SpeakerDevice) {
  command(AssistantBroadcast.broadcast("Intruder detected!"))
}

นำเข้าใบแจ้งยอด

เมื่อพัฒนาการทำงานอัตโนมัติ คุณอาจไม่ทราบวิธีนำเข้าองค์ประกอบต่างๆ ของ Home API ไปยังโค้ดเสมอไป

ระบบจะนำเข้าแอตทริบิวต์ลักษณะจากออบเจ็กต์ Companion ของลักษณะ

import com.google.home.matter.standard.OnOff.Companion.onOff

ระบบจะนำเข้าโครงสร้างข้อมูลที่กำหนดโดยลักษณะจากคลาสลักษณะ ซึ่งมีชื่อลงท้ายด้วย "-Trait" ดังนี้

import com.google.home.matter.standard.MediaPlaybackTrait.PlaybackStateEnum

ระบบจะนำเข้าคำสั่งลักษณะจากออบเจ็กต์ Companion ของลักษณะ

import com.google.home.matter.standard.Thermostat.Companion.setTemperatureSetpointHold