ควบคุมอุปกรณ์ใน 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 ซึ่งกำหนดไว้ในรูปแบบข้อมูลของระบบนิเวศ Google Home เป็น toggle() วิธีนี้จะเปลี่ยน onOff เป็น false หากเป็น true หรือ เป็น true หากเป็น false

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

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

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

do {
  try await onOffTraitTest.off()
  try await onOffTraitTest.on()
} catch let error 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 error 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 error 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!")
}

แอตทริบิวต์บางรายการอาจเป็นค่าว่างในข้อกำหนด 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 \(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)
  }
}