ควบคุมอุปกรณ์ใน iOS

คู่มือนี้เป็นคู่มือต่อเนื่องจากหัวข้อ การเข้าถึงอุปกรณ์และข้อมูลเมตาของอุปกรณ์ใน iOS และแนะนำ ตัวอย่างเพิ่มเติมเกี่ยวกับการควบคุมและการเข้าถึงอุปกรณ์

หากต้องการใช้ประเภทหรือลักษณะเฉพาะของอุปกรณ์ เช่น Matter OnOffTrait ที่ใช้ในตัวอย่างหลายๆ รายการในที่นี้ คุณต้องนำเข้าลักษณะเฉพาะเหล่านั้นก่อน

import GoogleHomeSDK
import GoogleHomeTypes

ตรวจสอบว่าลักษณะเฉพาะรองรับคำสั่งหรือไม่

ใช้ฟังก์ชัน supports ระดับลักษณะเฉพาะเพื่อตรวจสอบว่าอุปกรณ์หนึ่งๆ รองรับคำสั่งหรือไม่

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

// Check if the OnOff trait supports the toggle command.
if onOffTraitTest.supportsToggleCommand {
  print("onOffTrait supports toggle command")
} else {
  print("onOffTrait does not support stateful toggle command")
}

ส่งคำสั่งไปยังอุปกรณ์

การส่งคำสั่งจะคล้ายกับการอ่านแอตทริบิวต์สถานะจากลักษณะเฉพาะ หากต้องการ เปิดหรือปิดอุปกรณ์ ให้ใช้ OnOffTrait คำสั่ง Toggle ซึ่งกำหนดไว้ในโมเดลข้อมูลระบบนิเวศ Google Home เป็น toggle() เมธอดนี้จะเปลี่ยน onOff เป็น false หากเป็น true หรือเปลี่ยนเป็น true หากเป็น false

// Calling a command on a trait.
do {
  try await onOffTraitTest.toggle()
} catch let _ as HomeError {
  // Code for handling the exception
}

คำสั่งอาจแสดงข้อยกเว้นหากตรวจพบปัญหาเกี่ยวกับโฟลว์การดำเนินการ ในฐานะนักพัฒนาซอฟต์แวร์ คุณควรใช้บล็อก do-catch เพื่อจัดการข้อยกเว้นเหล่านี้อย่างเหมาะสม และแสดงข้อมูลโดยละเอียดแก่ผู้ใช้ในกรณีที่ ข้อผิดพลาดสามารถดำเนินการได้ ข้อยกเว้นที่ไม่ได้จัดการจะหยุดรันไทม์ของแอปและอาจทำให้แอปขัดข้อง

หรือใช้คำสั่ง off() หรือ on() เพื่อตั้งค่าสถานะอย่างชัดแจ้ง

do {
  try await onOffTraitTest.off()
  try await onOffTraitTest.on()
} catch let _ as HomeError {
  // Code for handling the exception
}

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

ส่งคำสั่งพร้อมพารามิเตอร์

คำสั่งบางรายการอาจใช้พารามิเตอร์ เช่น คำสั่งใน OnOffTrait หรือ LevelControlTrait

offWithEffect

// Turn off the light using the DyingLight effect.
do {
  try await onOffTraitTest.offWithEffect(
    effectIdentifier: Matter.OnOffTrait.EffectIdentifierEnum.dyingLight,
    effectVariant: 0
  )
} catch let _ as HomeError {
  // Code for handling the exception
}

moveToLevel

// Change the brightness of the light to 50%
do {
  try await levelControlTraitTest.moveToLevel(
    level: UInt8(127),
    transitionTime: 0,
    optionsMask: Matter.LevelControlTrait.OptionsBitmap(),
    optionsOverride: Matter.LevelControlTrait.OptionsBitmap()
  )
} catch let _ as HomeError {
  // Code for handling the exception
}

ตรวจสอบว่าลักษณะเฉพาะรองรับแอตทริบิวต์หรือไม่

อุปกรณ์บางเครื่องอาจรองรับลักษณะเฉพาะของ Matter แต่ไม่รองรับแอตทริบิวต์ที่เฉพาะเจาะจง ตัวอย่างเช่น อุปกรณ์ Cloud-to-cloud ที่ แมปกับ Matter อาจไม่รองรับแอตทริบิวต์ Matter ทุกรายการ หากต้องการจัดการกรณีเช่นนี้ ให้ใช้พร็อพเพอร์ตี้ isSupported ระดับลักษณะเฉพาะเพื่อตรวจสอบว่าอุปกรณ์หนึ่งๆ รองรับแอตทริบิวต์หรือไม่

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

// Check if the OnOff trait supports the onOff attribute.
if onOffTrait.attributes.$onOff.isSupported {
  print("onOffTrait supports onOff state")
} else {
  print("onOffTrait is for a command only device!")
}

แอตทริบิวต์บางรายการอาจเป็น Null ได้ในข้อกำหนด Matter หรือ สคีมา Cloud-to-cloud smart home สำหรับแอตทริบิวต์เหล่านี้ คุณสามารถตรวจสอบได้ว่า nil ที่แอตทริบิวต์ส่งคืนมานั้นเกิดจากอุปกรณ์ไม่รายงานค่าดังกล่าว หรือค่าของแอตทริบิวต์เป็น nil จริงๆ โดยใช้ isNullable นอกเหนือจาก isSupported

// Check if a nullable attribute is set or is not supported.
if let deviceType = await device.types.get(OnOffLightDeviceType.self) {
  if let onOffTrait = deviceType.traits[Matter.OnOffTrait.self] {
    if onOffTrait.attributes.startUpOnOff == nil {
      if onOffTrait.attributes.$startUpOnOff.isSupported {
        print(
          "onOffTrait supports startUpOnOff and it is nil. Check the spec for the contextual meaning."
        )
      } else {
        print("onOffTrait does not support startUpOnOff!")
      }
    } else {
      print(
        "onOffTrait supports startUpOnOff and it is set to \(String(describing: onOffTrait.attributes.startUpOnOff))"
      )
    }
  }
}

อัปเดตแอตทริบิวต์ลักษณะเฉพาะ

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

ความสามารถในการเปลี่ยนค่าของแอตทริบิวต์ขึ้นอยู่กับ 2 ปัจจัยต่อไปนี้

  • แอตทริบิวต์เขียนได้หรือไม่
  • ค่าของแอตทริบิวต์สามารถเปลี่ยนแปลงได้หรือไม่เมื่อส่งคำสั่งลักษณะเฉพาะ

เอกสารอ้างอิงสำหรับลักษณะเฉพาะและแอตทริบิวต์ของลักษณะเฉพาะจะให้ข้อมูลนี้

ดังนั้น การผสมผสานพร็อพเพอร์ตี้ที่กำหนดวิธีเปลี่ยนค่าของแอตทริบิวต์มีดังนี้

  • อ่านอย่างเดียวและ ไม่ได้รับผลกระทบ จากคำสั่งอื่นๆ ซึ่งหมายความว่าค่าของแอตทริบิวต์จะไม่เปลี่ยนแปลง เช่น แอตทริบิวต์ currentPosition ของ SwitchTrait

  • อ่านอย่างเดียวและ ได้รับผลกระทบ จากคำสั่งอื่นๆ ซึ่งหมายความว่าวิธีเดียวที่ค่าของแอตทริบิวต์จะเปลี่ยนแปลงได้คือการส่งคำสั่ง ตัวอย่างเช่น แอตทริบิวต์ currentLevelของLevelControlTrait เป็นแบบอ่านอย่างเดียว แต่คำสั่งต่างๆ เช่น moveToLevelสามารถเปลี่ยนค่าได้

  • เขียนได้และ ไม่ได้รับผลกระทบ จากคำสั่งอื่นๆ ซึ่งหมายความว่าคุณสามารถเปลี่ยนค่าของแอตทริบิวต์ได้โดยตรงโดยใช้ฟังก์ชัน update ของลักษณะเฉพาะ แต่จะไม่มีคำสั่งใดที่จะส่งผลต่อค่าของแอตทริบิวต์ เช่น แอตทริบิวต์ WrongCodeEntryLimit ของ DoorLockTrait

  • เขียนได้และ ได้รับผลกระทบ จากคำสั่งอื่นๆ ซึ่งหมายความว่าคุณสามารถเปลี่ยนค่าของแอตทริบิวต์ได้โดยตรงโดยใช้ฟังก์ชัน update ของลักษณะเฉพาะ และค่าของแอตทริบิวต์สามารถเปลี่ยนแปลงได้เมื่อส่งคำสั่ง ตัวอย่างเช่น แอตทริบิวต์ occupiedCoolingSetpoint ของ ThermostatTrait สามารถเขียนได้ แต่ก็อัปเดตได้ด้วยคำสั่ง setpointRaiseLower command

ตัวอย่างการใช้ฟังก์ชันอัปเดตเพื่อเปลี่ยนค่าของแอตทริบิวต์

ตัวอย่างนี้แสดงวิธีตั้งค่าแอตทริบิวต์ DoorLockTrait.wrongCodeEntryLimit อย่างชัดแจ้ง

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

ตัวอย่างเช่น

if doorLockTraitTest.attributes.$wrongCodeEntryLimit.isSupported {
  let _ = try await doorLockTraitTest.update {
    $0.setWrongCodeEntryLimit(3)
  }
}