เข้าถึงอุปกรณ์และข้อมูลเมตาของอุปกรณ์สำหรับ iOS

คุณเข้าถึง Device API ได้ผ่าน Home API สำหรับ iOS นำเข้าแพ็กเกจต่อไปนี้ลงในแอป

import GoogleHomeSDK
import GoogleHomeTypes

ดูข้อมูลเพิ่มเติมได้ที่โมเดลข้อมูลใน iOS

การจัดการข้อผิดพลาด

เมธอดบางอย่างใน Home API จะส่งHomeError ดังนั้นเราขอแนะนำให้คุณใช้บล็อก do-catch เพื่อตรวจหาHomeErrorในการเรียกเหล่านั้น

เมื่อจัดการ HomeError ให้ตรวจสอบฟิลด์ code และ message เพื่อดูว่าเกิดข้อผิดพลาดใด

ข้อผิดพลาดที่ไม่ได้จัดการจะส่งผลให้แอปขัดข้อง

ดูข้อมูลเพิ่มเติมได้ที่ การจัดการข้อผิดพลาด

ดูตัวอย่างได้ที่ส่งคำสั่งไปยังอุปกรณ์

ตัวอย่างการเรียก

รับรายการอุปกรณ์

เมื่ออ้างอิงถึงออบเจ็กต์ Home ให้เรียกใช้ devices() เพื่อรับ Query ของอุปกรณ์ที่เข้าถึงได้ เรียกใช้เมธอด Query's batched() ซึ่งจะปล่อย Set ที่แสดงสถานะปัจจุบันของบ้านเมื่อมีการเปลี่ยนแปลงข้อมูลเมตาของอุปกรณ์ ทุกครั้ง หรือโทรหา Query.list() เพื่อดู ภาพรวมของอุปกรณ์ที่พร้อมใช้งาน นี่คือเมธอดที่สะดวกซึ่งจะสมัครใช้บริการสตรีม batched() และแสดงผลค่าแรกที่ปล่อยออกมา Query.stream() สร้างสตรีมที่ส่งค่าใหม่เมื่อมีการเปลี่ยนแปลงข้อมูลเมตาของอุปกรณ์ เช่น ชื่อ ห้อง หรือโครงสร้าง ภายในแล้ว ฟังก์ชันนี้จะใช้ batched() และส่งเฉพาะพร็อพเพอร์ตี้ที่เปลี่ยนแปลง เท่านั้น

// Get a list of all devices accessible to the user
let homeDevices = try await self.home.devices().list()

จากนั้น คุณจะเข้าถึงสถานะของอุปกรณ์แต่ละเครื่องและส่งคำสั่งที่รองรับ ไปยังอุปกรณ์ได้

รับประเภทของอุปกรณ์

หากต้องการดูประเภทอุปกรณ์ที่เชื่อมโยงกับอุปกรณ์ ให้อ่านพร็อพเพอร์ตี้ types ของอุปกรณ์ ซึ่งจะแสดงผล DeviceTypeController

โทรหา DeviceTypeController.subscribe(_:) เพื่อสมัครรับข้อมูลอัปเดตสำหรับ อุปกรณ์ประเภทใดประเภทหนึ่ง

let devices = try await self.home.devices().list()
if let device = devices.first(where: { $0.id == myDeviceId }) {
  var receivedUpdate1 = false
  var receivedUpdate2 = false
  device.types.subscribe(OnOffLightDeviceType.self)
    .assertNoFailure()
    .sink { device in
      if !receivedUpdate1 {
        receivedUpdate1 = true
        Task {
          try await device.matterTraits.onOffTrait?.on()
        }
        return
      }
      if !receivedUpdate2 {
        receivedUpdate2 = true
        return
      }
      fatalError("Received unexpected update")
    }
}

หากอุปกรณ์ไม่รองรับประเภทอุปกรณ์ที่ระบุ ระบบจะแสดง Empty Publisher ที่เสร็จสมบูรณ์ทันที

หากอุปกรณ์รองรับอุปกรณ์ประเภทใดประเภทหนึ่ง คุณจะรับแฮนเดิลสำหรับอุปกรณ์ประเภทนั้นได้โดยการเรียกใช้ get()

if let device = devices.first(where: { $0.id == myDeviceId }) {
  let deviceType = await device.types.get(OnOffLightDeviceType.self)
}

หากอุปกรณ์ไม่รองรับประเภทที่ระบุ ระบบจะแสดง nil

โทรหา DeviceTypeController.subscribeAll() เพื่อรับ Publisher ของ DeviceTypeCollection คลาสนี้ช่วยให้คุณตรวจสอบได้ว่าอุปกรณ์มีประเภทอุปกรณ์ที่เฉพาะเจาะจงหรือไม่

if let device = devices.first(where: { $0.id == myDeviceId }) {
  device.types.subscribeAll()
    .assertNoFailure()
    .sink { types in
      let lightDeviceType = types[OnOffLightDeviceType.self]
      let fanDeviceType = types[FanDeviceType.self]
    }
}

รับลักษณะประเภทอุปกรณ์

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

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

การชนกันของลักษณะอีกประเภทอาจเกิดขึ้นเมื่ออุปกรณ์มีลักษณะ 2 อย่างที่มีชื่อเดียวกัน เช่น onOff อาจอ้างอิงถึงอินสแตนซ์ของลักษณะOnOffมาตรฐาน หรืออาจอ้างอิงถึงอินสแตนซ์ของลักษณะOnOffที่ผู้ผลิตกำหนด หากต้องการขจัดความคลุมเครือที่อาจเกิดขึ้นเกี่ยวกับลักษณะที่ต้องการ ให้อ้างอิงลักษณะผ่านคอลเล็กชันลักษณะ 2 รายการอย่างใดอย่างหนึ่งในอุปกรณ์แต่ละประเภท

สำหรับลักษณะมาตรฐาน ซึ่งก็คือลักษณะที่คล้ายกับMatterคลัสเตอร์มาตรฐาน ให้ใช้ matterTraits เช่น หากต้องการรับลักษณะเฉพาะสำหรับประเภทอุปกรณ์ไฟหรี่ได้ ให้ทำดังนี้

if let dimmableLightDeviceType =
  await device.types.get(DimmableLightDeviceType.self)
{
  // Accessing standard trait on the type.
  let levelControlTrait =
    dimmableLightDeviceType.matterTraits.levelControlTrait.self
}

สำหรับลักษณะของ Google ให้ใช้ googleTraits ดังนี้

if let doorbellDeviceType = await device.types.get(GoogleDoorbellDeviceType.self) {
  // Accessing Google trait on the type.
  let doorbellPressTrait =
    doorbellDeviceType.googleTraits.doorbellPressTrait.self
}

หากต้องการเข้าถึงลักษณะเฉพาะของผู้ผลิต ให้อ้างอิงผ่านtraits พร็อพเพอร์ตี้ แต่ให้ขึ้นต้นด้วยชื่อแพ็กเกจของผู้ผลิต

let deviceType = await device1?.types.get(OnOffLightDeviceType.self)
// Accessing custom trait on the type.
if let spinnerTrait = deviceType?.traits[ExampleOrganization.SpinnerTrait.self] {
  let rpmVal = spinnerTrait.attributes.rpm
}

อ่านสถานะอุปกรณ์

ดูตัวอย่างการตรวจสอบแอตทริบิวต์ OnOff จากลักษณะเปิด/ปิดของอุปกรณ์

let lightDevices = devices.filter {
  $0.types.contains(OnOffLightDeviceType.self)
}
let light1 = lightDevices.first
let lightDeviceTypeOptional = await light1?.types.get(OnOffLightDeviceType.self)
if let onOffTrait = lightDeviceTypeOptional?.matterTraits.onOffTrait {
  let onOffVal = onOffTrait.attributes.onOff
}

ดูรายการอุปกรณ์ที่มีลักษณะเฉพาะ

หากต้องการดูรายการอุปกรณ์ที่มีลักษณะเฉพาะ คุณต้องวนซ้ำ ในอุปกรณ์ ประเภทอุปกรณ์ของแต่ละอุปกรณ์ และลักษณะของแต่ละประเภทอุปกรณ์ ตัวอย่างเช่น หากต้องการดูรายการอุปกรณ์ในบ้านที่มีลักษณะเปิด/ปิดทั้งหมด ให้ทำดังนี้

// Get all light devices that support levelControl
var levelControlDevices: [HomeDevice] = []
var allDevices = try await home.devices().list()
for device in allDevices {
  if let deviceType = await device.types.get(OnOffLightDeviceType.self) {
    if deviceType.traits.contains(Matter.LevelControlTrait.self) {
      levelControlDevices.append(device)
    }
  }
}

ดูรายการลักษณะทั้งหมดที่พร้อมใช้งานใน Home API ได้ที่ดัชนีลักษณะใน iOS

ดูรายการอุปกรณ์ที่มีประเภทอุปกรณ์คล้ายกัน

หากต้องการดูรายการอุปกรณ์ที่แสดงไฟทั้งหมดในบ้าน ให้ทำดังนี้

// Get a list of devices with similar device types (lights)
let lightDevices =
  try await self.home.devices().list().compactMap {
    $0.types.contains(DimmableLightDeviceType.self)
      || $0.types.contains(OnOffLightDeviceType.self)
      || $0.types.contains(ColorTemperatureLightDeviceType.self)
      || $0.types.contains(ExtendedColorLightDeviceType.self)
  }

มีอุปกรณ์หลายประเภทใน Home API ที่อาจแสดงถึงประเภทอุปกรณ์หลัก เช่น ไม่มีประเภทอุปกรณ์ "หลอดไฟ" แต่จะมีอุปกรณ์ 4 ประเภทที่แตกต่างกันซึ่งอาจแสดงถึงหลอดไฟ ดังที่แสดงในตัวอย่างก่อนหน้า ดังนั้น หากต้องการดูภาพรวมของอุปกรณ์ประเภทระดับสูงในบ้าน คุณต้องรวมอุปกรณ์หลายประเภท

ดูรายการประเภทอุปกรณ์ทั้งหมดและลักษณะของอุปกรณ์ที่พร้อมใช้งานใน Home API ได้ที่ประเภทอุปกรณ์ที่รองรับใน iOS

ดูชื่อผู้ให้บริการ รหัสผู้ให้บริการ หรือรหัสผลิตภัณฑ์สำหรับอุปกรณ์

ลักษณะBasicInformationTrait ประกอบด้วยข้อมูล เช่น รหัสผู้ให้บริการ รหัสผลิตภัณฑ์ ชื่อผลิตภัณฑ์ และ หมายเลขซีเรียลของอุปกรณ์

guard
  let vendorName =
    basicInfoTrait.attributes.vendorName
else {
  fatalError("Failed to get vendorName")
}
guard
  let vendorID =
    basicInfoTrait.attributes.vendorID
else {
  fatalError("Failed to get vendorID")
}
guard
  let productID =
    basicInfoTrait.attributes.productID
else {
  fatalError("Failed to get productID")
}

การระบุอุปกรณ์แบบคลาวด์ต่อคลาวด์สำหรับผู้ผลิตอุปกรณ์

หากคุณเป็นผู้ผลิตอุปกรณ์และสร้างCloud-to-cloudอุปกรณ์ คุณสามารถระบุCloud-to-cloudอุปกรณ์ผ่านลักษณะBasicInformationได้โดยรวมฟิลด์สตริงเหล่านี้ไว้ในคำตอบSYNCของอุปกรณ์

  • Connectivity Standards Alliance (CSA) ออกรหัสผู้ให้บริการ: "matterOriginalVendorId": "0xfff1",

  • ตัวระบุผลิตภัณฑ์ที่ระบุผลิตภัณฑ์ของผู้ขายได้อย่างไม่ซ้ำกัน "matterOriginalProductId": "0x1234",

  • ตัวระบุที่ไม่ซ้ำกันสำหรับอุปกรณ์ ซึ่งสร้างขึ้นในลักษณะเฉพาะของผู้ผลิต "matterUniqueId": "matter-device-id",

เมื่อป้อนฟิลด์สตริงเหล่านี้ ให้ใช้Matter รหัสผู้ให้บริการและรหัสผลิตภัณฑ์หากมี หากคุณไม่ได้เป็นสมาชิก CSA และไม่ได้รับมอบหมายรหัสเหล่านี้ คุณสามารถเว้นช่อง matterOriginalVendorId และ matterOriginalProductId ว่างไว้ แล้วระบุ matterUniqueId เป็นตัวระบุได้

ตัวอย่างการตอบกลับ SYNC แสดงการใช้ฟิลด์ต่อไปนี้

{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "agentUserId": "1836.15267389",
    "devices": [
      {
        "id": "456",
        "type": "action.devices.types.LIGHT",
        "traits": [
          "action.devices.traits.OnOff",
          "action.devices.traits.Brightness",
          "action.devices.traits.ColorSetting",
        ],
        "willReportState": true,
        "deviceInfo": { ... },
        "matterOriginalVendorId": "0xfff1",
        "matterOriginalProductId": "0x1234",
        "matterUniqueId": "matter-device-id",
        "otherDeviceIds": [
          {
            "deviceId": "local-device-id",
          }
        ]
      }
    ]
  }
}

ดูข้อมูลเพิ่มเติมได้ที่เอกสารประกอบของ Cloud-to-cloud SYNC

ข้อมูลเมตาของอุปกรณ์และลักษณะ

อุปกรณ์และลักษณะใน Home API มีข้อมูลเมตาที่เชื่อมโยงอยู่ ซึ่งจะช่วยในการจัดการประสบการณ์ของผู้ใช้ในแอปได้

ลักษณะแต่ละอย่างใน Home API มีพร็อพเพอร์ตี้ sourceConnectivity ซึ่งมีข้อมูลเกี่ยวกับสถานะออนไลน์และสถานที่ตั้งของลักษณะ (การกำหนดเส้นทางในพื้นที่หรือระยะไกล)

รับประเภทหลักของอุปกรณ์

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

if let deviceType =
  await device?.types.get(HumiditySensorDeviceType.self)
{
  if deviceType.metadata.isPrimaryType {
    print("Humidity Sensor is the primary type on this device.")
  } else {
    print("Humidity Sensor isn't the primary type on this device.")
  }
}

ตรวจสอบว่าลักษณะออนไลน์อยู่หรือไม่

อ่านconnectivityStateพร็อพเพอร์ตี้เพื่อตรวจสอบการเชื่อมต่อลักษณะ

let levelControlConnectivity =
  levelControlTrait.metadata.sourceConnectivity
  .connectivityState

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

ตรวจสอบการเชื่อมต่อของอุปกรณ์

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

let lightConnectivity =
  dimmableLightDeviceType.metadata.sourceConnectivity
  .connectivityState

สถานะ partiallyOnline อาจปรากฏในกรณีที่มีอุปกรณ์หลายประเภท เมื่อไม่มีการเชื่อมต่ออินเทอร์เน็ต Matter ลักษณะมาตรฐาน อาจยังออนไลน์อยู่เนื่องจากการกำหนดเส้นทางในพื้นที่ แต่ลักษณะที่อิงตามระบบคลาวด์จะ ออฟไลน์

ตรวจสอบการกำหนดเส้นทางเครือข่ายของลักษณะ

นอกจากนี้ คุณยังดูสถานที่ตั้งของลักษณะได้ใน Home API dataSourceLocality จะระบุว่ามีการกำหนดเส้นทางลักษณะจากระยะไกล (ผ่านระบบคลาวด์) ในเครื่อง (ผ่านฮับในเครื่อง) หรือแบบเพียร์ทูเพียร์ (จากอุปกรณ์หนึ่งไปยังอีกอุปกรณ์หนึ่งโดยตรง ไม่ต้องใช้ฮับ)

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

let levelControlLocality =
  levelControlTrait.metadata.sourceConnectivity
  .dataSourceLocality

ตรวจสอบการกำหนดเส้นทางเครือข่ายสำหรับอุปกรณ์

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

let lightLocality =
  dimmableLightDeviceType.metadata.sourceConnectivity.dataSourceLocality

สถานะ mixed อาจสังเกตได้ในสถานการณ์ที่คล้ายกัน กับการเชื่อมต่อ partiallyOnline โดยลักษณะบางอย่างจะอยู่ในระบบคลาวด์ ขณะที่ลักษณะอื่นๆ จะอยู่ในเครื่อง

เปลี่ยนชื่ออุปกรณ์

เรียกใช้เมธอด setName(_:) เพื่อเปลี่ยนชื่ออุปกรณ์

let updatedDevice = try await theDevice.setName("new device name")

เมื่อเปลี่ยนชื่ออุปกรณ์ HomeDevice struct เดิมจะยังคงเหมือนเดิม และการเปลี่ยนแปลงจะแสดงในออบเจ็กต์ HomeDevice ที่อัปเดตแล้วซึ่งส่งคืน

รายการ API

เมื่อสร้างอินสแตนซ์ของ Home แล้ว คุณจะเข้าถึง Device API ต่อไปนี้ผ่านอินสแตนซ์ได้

API คำอธิบาย
device(id:) แสดง Publisher สำหรับอุปกรณ์ที่ระบุซึ่งจะปล่อยสถานะอุปกรณ์ทุกครั้งที่มีการเปลี่ยนแปลง
devices() รับอุปกรณ์ทั้งหมดในโครงสร้างทั้งหมดในบัญชี Google แสดงผล Query<HomeDevice> ที่มีตัวเลือกการดึงข้อมูลและการกรองเพิ่มเติม

เมื่อมี HomeDevice แล้ว คุณจะเข้าถึง API ต่อไปนี้ได้

API คำอธิบาย
id รหัสระบบที่ไม่ซ้ำกันของอุปกรณ์
name ชื่ออุปกรณ์ที่ผู้ใช้ระบุ
structureID รหัสของโครงสร้างที่กำหนดให้กับอุปกรณ์ แสดงผล String?
roomID รหัสของห้องที่กำหนดอุปกรณ์ไว้ แสดงผล String?
types รับประเภทที่เฉพาะเจาะจงหรือประเภทที่มีทั้งหมดในอุปกรณ์
isMatterDevice หากอุปกรณ์ได้รับการสนับสนุนจาก Matter
sourceConnectivity การเชื่อมต่อแหล่งที่มาของอุปกรณ์ ซึ่งแสดงสถานะการเชื่อมต่อที่รวบรวมแล้วและตำแหน่งเครือข่ายของลักษณะของอุปกรณ์