คุณใช้ DSL ของการทำงานอัตโนมัติเพื่อสร้างการทำงานอัตโนมัติที่ซับซ้อนกว่าที่กล่าวถึงในคู่มือ DSL - การทำงานอัตโนมัติพื้นฐานใน Android ได้
ตามลำดับที่มีการดำเนินการหลายอย่าง
การทำงานอัตโนมัติสามารถทำได้มากกว่า 1 อย่าง ตัวอย่างเช่น คุณสามารถมีโหนด action หลายโหนดที่ทำงานตามลำดับแทนโหนด action โหนดเดียวได้ ดังนี้
automation {
sequential {
starter<_>(...)
condition {...}
action {...}
action {...}
action {...}
}
}
ตามลำดับที่มีการดำเนินการแบบขนานหลายรายการ
หากคุณวางโหนด action หลายโหนดในโหนด parallel การดำเนินการจะทำงานพร้อมกัน
automation {
sequential {
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.
automation {
sequential {
val contactState = starter<_>(
contactSensor,
ContactSensorDevice,
BooleanState,
)
val lightState = stateReader<_>(
light,
DimmableLightDevice,
OnOff,
)
condition {
// Door opened (contact sensor open)
expression = contactState.stateValue equals false
}
// Conditionally turn on the light if it's off
ifThen(lightState.onOff equals false) {
action(light, DimmableLightDevice) { command(OnOff.on()) }
}
// Continue executing subsequent actions in the sequential flow
action(structure) {
command(AssistantBroadcast.broadcast("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.
automation {
sequential {
val doorLockEvent = starter<_>(
doorLock,
DoorLockDevice,
LockOperationEvent,
)
val lightState = stateReader<_>(
light,
DimmableLightDevice,
OnOff,
)
condition {
expression =
doorLockEvent.lockOperationType equals LockOperationTypeEnum.Unlock
}
ifThen(lightState.onOff equals false) {
action(light, DimmableLightDevice) { command(OnOff.on()) }
}.orElse {
action(structure) {
command(AssistantBroadcast.broadcast("Welcome home!"))
}
}
}
}
เชื่อมโยงหลายเงื่อนไขตามลำดับ
คุณสามารถเชื่อมโยงบล็อก .elseIf(...) { ... } ที่ไม่บังคับอย่างน้อย 1 บล็อกเพื่อประเมินเงื่อนไขหลายรายการตามลำดับได้ ระบบจะดำเนินการกับสาขาแรกที่มีเงื่อนไขที่ประเมินเป็น true และข้ามสาขาที่เหลือทั้งหมด หากไม่มีเงื่อนไขใดที่ประเมินเป็น true บล็อก .orElse { ... } ที่ไม่บังคับจะทำงาน (หากระบุไว้) ดังนี้
// Adjust climate controls based on room temperature changes.
automation {
sequential {
val tempStarter = starter<_>(
tempSensor,
TemperatureSensorDevice,
TemperatureMeasurement,
)
// If temperature is high (>= 28°C / 2800 mC), switch thermostat to Cool mode
ifThen(tempStarter.measuredValue greaterThanOrEquals 2800) {
action(thermostat, ThermostatDevice) {
command(
SimplifiedThermostat.setSystemMode(
SimplifiedThermostatSystemModeEnum.Cool
)
)
}
}.elseIf(tempStarter.measuredValue lessThan 1800) {
// If temperature is low (< 18°C / 1800 mC), switch to Heat mode
action(thermostat, ThermostatDevice) {
command(
SimplifiedThermostat.setSystemMode(
SimplifiedThermostatSystemModeEnum.Heat
)
)
}
}.orElse {
// Otherwise, turn on the fan
action(fan, FanDevice) {
command(OnOff.on())
}
}
}
}
โฟลว์แบบมีเงื่อนไขที่ซ้อนกัน
บล็อกแบบมีเงื่อนไขสามารถซ้อนอยู่ภายในบล็อก ifThen, elseIf หรือ orElse อื่นๆ รวมถึงรวมกับโหนด parallel, delayFor และ stateReader ได้
บล็อก ifThen, elseIf และ orElse จะเรียกใช้เนื้อหาเป็นโฟลว์ตามลำดับ คุณสามารถวางโหนดตามลำดับภายในแต่ละสาขาได้ ซึ่งรวมถึงบล็อก action, stateReader, parallel, delayFor และ ifThen ที่ฝังอยู่
ความล่าช้า
คุณสามารถหยุดการทำงานอัตโนมัติชั่วคราวได้โดยใช้คีย์เวิร์ด delayFor ซึ่งจะใช้อาร์กิวเมนต์ java.time.Duration เพื่อแสดงระยะเวลาที่ต้องการหยุดชั่วคราวก่อนที่จะดำเนินการต่อ ระยะเวลาการหยุดชั่วคราวอาจสั้นเพียง 5 วินาทีหรือนานถึง 24 ชั่วโมง
ตัวอย่างเช่น หากต้องการเปิด/ปิดไฟ 4 ครั้งโดยหยุดชั่วคราว 5 วินาทีระหว่างการเปิด/ปิดแต่ละครั้ง ให้ทำดังนี้
sequential {
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
delayFor(Duration.ofSeconds(5))
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
delayFor(Duration.ofSeconds(5))
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
delayFor(Duration.ofSeconds(5))
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
}
ทริกเกอร์การระงับ
การระงับทริกเกอร์เป็นความสามารถที่ช่วยให้การทำงานอัตโนมัติของคุณละเว้นstarterเป็นระยะเวลาที่ระบุหลังจากเหตุการณ์ทริกเกอร์เริ่มต้น ตัวอย่างเช่น หากการทำงานอัตโนมัติมีstarterที่ทริกเกอร์โดยการตรวจจับการเคลื่อนไหว และคุณระบุระยะเวลาการระงับทริกเกอร์เป็น 5 นาที เมื่อstarterทริกเกอร์ ระบบจะไม่ทริกเกอร์อีกเป็นเวลา 5 นาทีถัดไป ซึ่งจะป้องกันไม่ให้การทำงานอัตโนมัติทริกเกอร์ซ้ำๆ อย่างรวดเร็ว
หากต้องการใช้การระงับทริกเกอร์กับการทำงานอัตโนมัติ ให้ใช้คีย์เวิร์ด suppressFor พร้อมอาร์กิวเมนต์ java.time.Duration ซึ่งแสดงระยะเวลาที่ต้องรอก่อนตอบสนองต่อทริกเกอร์ที่ตามมา
ระยะเวลาการระงับอาจสั้นเพียง 5 วินาทีหรือนานถึง 24 ชั่วโมง
automation {
sequential {
val starterNode = starter<_>(device, OccupancySensor, MotionDetection)
suppressFor(Duration.ofMinutes(30))
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
}
โปรดทราบว่าการระงับทริกเกอร์จะส่งผลต่อstartersทั้งหมดในการทำงานอัตโนมัติที่เกิดขึ้นก่อนsuppressFor
จำกัดจำนวนการดำเนินการ
คุณจำกัดจำนวนครั้งที่อนุญาตให้การทำงานอัตโนมัติทำงานได้
เช่น คุณอาจต้องการตั้งค่าการทำงานอัตโนมัติแบบครั้งเดียวที่สั่งให้หุ่นยนต์ดูดฝุ่นทำงานขณะที่คุณไม่อยู่บ้านในวันนั้น
โดยตั้งค่าช่องข้อมูลเมตา maxExecutionCount ของการทำงานอัตโนมัติ
ตัวอย่างต่อไปนี้เป็นการทำงานอัตโนมัติที่ดำเนินการได้เพียงครั้งเดียว
automation { // The automation can only be executed once. maxExecutionCount = 1 // When the door lock state changes sequential { val doorLockEvent = starter<_>(doorLock, DoorLockDevice, LockOperationEvent) // if the door is unlocked condition() { expression = (doorLockEvent.lockOperationType equals LockOperationTypeEnum.Unlock) } // turn the light on action(light, DimmableLightDevice) { command(OnOff.on()) } } }
ระบบจะลบการทำงานอัตโนมัติทันทีเมื่อดำเนินการครั้งสุดท้ายเสร็จสมบูรณ์และถึงวันที่ maxExecutionCount รายการประวัติของการทำงานอัตโนมัติจะยังคงอยู่ในแท็บGoogle Home app (GHA) กิจกรรม รวมถึงautomation_id
ตั้งค่าแอตทริบิวต์ลักษณะในการดำเนินการ
วิธีตั้งค่าแอตทริบิวต์ลักษณะ
- สร้างโหนด
updateภายในโหนดactionโดยรวมลักษณะที่เกี่ยวข้องเป็นอาร์กิวเมนต์ของโหนดupdateดังนี้action(deviceReference, deviceType) { update(trait) { } } - ภายในโหนด
updateสำหรับแต่ละแอตทริบิวต์ที่จะแก้ไข ให้ใช้ฟังก์ชัน Mutator และส่งค่าใหม่ให้ วิธีสร้างชื่อฟังก์ชัน Mutator- ใช้อักษรตัวพิมพ์ใหญ่สำหรับชื่อแอตทริบิวต์
- โดยขึ้นต้นด้วยคำว่า
set
defaultMoveRateคุณจะต้องใช้ฟังก์ชัน Mutator ชื่อsetDefaultMoveRate
โปรดทราบว่าโหนด update สามารถมีฟังก์ชัน Mutator ได้หลายฟังก์ชัน ตัวอย่างการอัปเดตแอตทริบิวต์ 2 รายการมีดังนี้
action(device, Fan) {
update(FanControl) {
setPercentSetting(50u)
setRockSetting(FanControlCluster.RockBitmap.rockUpDown)
}
}