การทำงานอัตโนมัติของอุปกรณ์แบบหลายส่วนใน Android

การทำงานอัตโนมัติอาจอ้างอิงอุปกรณ์หลายส่วนในลักษณะเดียวกับการทำงานอัตโนมัติที่ไม่ได้ใช้อุปกรณ์หลายส่วน

ขั้นแรก ให้รับส่วนประกอบตามปกติ ดูวิธีใช้อุปกรณ์ หลายส่วนได้ที่ อุปกรณ์หลายส่วน

จากนั้น สร้าง AutomationPartPathสำหรับแต่ละส่วนที่ต้องการใช้ในการทำงานอัตโนมัติ ซึ่งจะช่วยให้คุณอ้างอิงส่วนนั้นในตัวเริ่ม เงื่อนไข และ การดำเนินการของการทำงานอัตโนมัติได้

// Obtain a reference to the device:
val multipartDevices = structure.devices(enableMultipartDevices = true).first().toList()

val lights = multipartDevices.filter { it.has(OnOffLightDevice) && it.has(OnOff) }

val light = lights.first()

// get the AutomationPartPath for the device
val lightPartPath = light.automationPart(light.part(OnOffLightDevice).first())

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

ตัวอย่างเช่น ใน Automation API ระบบอาจถือว่าประเภทอุปกรณ์ Refrigerator เป็นอุปกรณ์หลายส่วน ซึ่งประกอบด้วย RefrigeratorDevice รูทที่สามารถมีตู้ย่อยหลายตู้ เช่น ตู้แช่แข็งหรือตู้มาตรฐานประเภท TemperatureControlledCabinetDevice

หากต้องการสร้างการทำงานอัตโนมัติของตู้เย็น คุณจะต้องโต้ตอบกับลักษณะมาตรฐาน 2 อย่าง Matter เป็นหลัก ดังนี้

  • RefrigeratorAlarm: แสดงการแจ้งเตือนสถานะประตูผ่านแอตทริบิวต์ doorOpen ของช่อง state
  • RefrigeratorAndTemperatureControlledCabinetMode: อนุญาตให้อ่านและสั่งการโหมดต่างๆ เช่น การเรียกใช้คำสั่งอย่าง changeToMode เพื่อเปลี่ยนไปใช้โหมดต่างๆ เช่น LowEnergy, RapidCool หรือ LowNoise

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

import com.google.home.automation.action
import com.google.home.automation.automation
import com.google.home.automation.condition
import com.google.home.automation.equals
import com.google.home.automation.starter
import com.google.home.google.AssistantBroadcast
import com.google.home.google.Notification
import com.google.home.matter.standard.OnOff
import com.google.home.matter.standard.OnOffLightDevice
import com.google.home.matter.standard.RefrigeratorAlarm
import com.google.home.matter.standard.RefrigeratorAlarm.Companion.state
import com.google.home.matter.standard.RefrigeratorDevice
import com.google.home.matter.standard.SpeakerDevice
import java.time.Duration

val structure: Structure = home.structures().first()

// Fetch devices using the multipart device model.
var multipartDevices = homeManager.devices(enableMultipartDevices = true)

// Obtain a reference to the refrigerator device.
val refrigeratorDevice = multipartDevices.first {
  it.has(TemperatureControlledCabinetDevice) &&
  it.has(RefrigeratorAndTemperatureControlledCabinetMode) &&
  it.has(RefrigeratorAlarm)
}

// Get all temperature-controlled cabinet parts of the refrigerator
val cabinets = refrigeratorDevice.parts(TemperatureControlledCabinetDevice)

// Find the cabinet part with the 'refrigerator' semantic tag
val refrigeratorCabinet = cabinets.firstOrNull {
  it.metadata.tags.contains(SemanticTag.Refrigerator.refrigerator)
}

val cabinetPartPath = refrigeratorCabinet.automationPath(TemperatureControlledCabinetDevice)

val speaker = home.devices().list().first { device -> device.has(SpeakerDevice) }

val refrigeratorDoorAlert = automation {
  name = "Refrigerator Door Open Alert"
  description = "Warn when the refrigerator door has been open for over 2 min"
  isActive = true

  sequential {
    // 1. Starter: Monitor the refrigerator door alarm trait
    val alarmStarter = starter<_>(cabinetPartPath, RefrigeratorAlarm)

    // 2. Condition: Ensure the 'doorOpen' alarm remains active for 2 continuous min
    condition {
      expression = alarmStarter.state.doorOpen equals true
      forDuration(Duration.ofMinutes(2))
    }

    // 3. Actions: Execute parallel reactions
    parallel {
      // Broadcast warning to household speakers
      action(speaker, SpeakerDevice) {
        command(AssistantBroadcast.broadcast("The refrigerator door has been left open!"))
      }

      // Push a notification alerts to home members' mobile devices
      action(structure) {
        command(Notification.sendNotifications(
          "Fridge Alert",
          { body = "The refrigerator door has been open for over 2 min" }
        ))
      }
    }
  }
}

ตัวอย่างต่อไปนี้จะเปลี่ยนตู้เย็นเป็นโหมดประหยัดพลังงานเมื่อตรวจพบว่าไม่มีใครอยู่บ้าน

import com.google.home.automation.action
import com.google.home.automation.automation
import com.google.home.automation.condition
import com.google.home.automation.equals
import com.google.home.automation.starter
import com.google.home.google.AreaPresenceState
import com.google.home.google.AreaPresenceState.Companion.presenceState
import com.google.home.google.AreaPresenceStateTrait.PresenceState
import com.google.home.matter.standard.RefrigeratorAndTemperatureControlledCabinetMode
import com.google.home.matter.standard.RefrigeratorAndTemperatureControlledCabinetMode.Companion.changeToMode
import com.google.home.matter.standard.RefrigeratorDevice
import com.google.home.matter.standard.TemperatureControlledCabinetDevice

val structure: Structure = home.structures().first()

// Fetch devices using the multipart device model.
var multipartDevices = homeManager.devices(enableMultipartDevices = true)

// Obtain a reference to the refrigerator device.
val refrigeratorDevice = multipartDevices.first {
  it.has(TemperatureControlledCabinetDevice) &&
  it.has(RefrigeratorAndTemperatureControlledCabinetMode) &&
  it.has(RefrigeratorAlarm)
}

val refrigeratorPartPath = refrigeratorDevice.automationPart(refrigeratorDevice.part(RefrigeratorDevice).first())

// Get all temperature-controlled cabinet parts of the refrigerator
val cabinets = refrigeratorDevice.parts(TemperatureControlledCabinetDevice )

// Find the cabinet part with the 'refrigerator' semantic tag
val refrigeratorCabinet = cabinets.firstOrNull {
  it.metadata.tags.contains(SemanticTag.Refrigerator.refrigerator)
}

val refrigeratorEcoMode = automation {
  name = "Refrigerator Eco Mode"
  description = "Automatically changes refrigerator to low energy mode when house is vacant."
  isActive = true

  sequential {
    // 1. Starter: Monitor household presence changes
    val presenceStarter = starter<_>(structure, AreaPresenceState)

    // 2. Condition: Verify presence state transitions to vacant
    condition {
      expression = presenceStarter.presenceState equals PresenceState.PresenceStateVacant
    }

    // 3. Action: Set refrigerator cabinet Mode to 'Low Energy' (e.g. Mode 1u)
    action(refrigeratorPartPath {
      command(RefrigeratorAndTemperatureControlledCabinetMode.changeToMode(1u))
    }
  }
}