คุณเข้าถึง 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()
จากนั้นคุณจะเข้าถึงสถานะของอุปกรณ์แต่ละเครื่องและส่งคำสั่งไปยังอุปกรณ์ได้
เมื่อใช้ Home API เวอร์ชัน 1.8 คุณจะมีตัวเลือกให้ API แสดง
อุปกรณ์แบบหลายส่วนแต่ละเครื่องเป็นอุปกรณ์เดียวโดยตั้งค่าพารามิเตอร์ enableMultipartDevices ของเมธอด devices() เป็น true ดูข้อมูลเพิ่มเติมได้ที่
อุปกรณ์แบบหลายพาร์ทใน iOS
รับประเภทของอุปกรณ์
หากต้องการดูประเภทอุปกรณ์ที่เชื่อมโยงกับอุปกรณ์ ให้อ่านพร็อพเพอร์ตี้ 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 _ = 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.traits[Google.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] = [] let 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 (Alliance) รหัสผู้ให้บริการที่ออกให้
"matterOriginalVendorId": "0xfff1",รหัสระบุผลิตภัณฑ์ที่ระบุผลิตภัณฑ์ของผู้ขายได้อย่างไม่ซ้ำกัน
"matterOriginalProductId": "0x1234",ตัวระบุที่ไม่ซ้ำกันสำหรับอุปกรณ์ ซึ่งสร้างขึ้นในลักษณะเฉพาะของผู้ผลิต
"matterUniqueId": "matter-device-id",
เมื่อป้อนฟิลด์สตริงเหล่านี้ ให้ใช้Matter
รหัสผู้ให้บริการและรหัสผลิตภัณฑ์หากมี หากคุณไม่ได้เป็นAllianceสมาชิกและไม่ได้รับรหัสเหล่านี้ คุณสามารถ
ปล่อยช่อง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 ลักษณะมาตรฐาน
อาจยังออนไลน์อยู่เนื่องจากการกำหนดเส้นทางในพื้นที่ แต่ลักษณะที่อิงตามระบบคลาวด์จะ
ออฟไลน์
รับที่อยู่ IP ของอุปกรณ์
หากต้องการค้นหาที่อยู่ IP ของอุปกรณ์ ให้ใช้แอตทริบิวต์ networkInterfaces ของ
GeneralDiagnosticsTrait
ระบบจะแสดงที่อยู่เป็นออบเจ็กต์ Data ซึ่งคุณจัดรูปแบบเป็นสตริง IPv4 หรือ IPv6 มาตรฐานได้โดยใช้เฟรมเวิร์ก Network ดังนี้
func getIpAddresses(trait: Matter.GeneralDiagnosticsTrait) -> [String] {
let interfaces = trait.attributes.networkInterfaces ?? []
var ipAddresses: [String] = []
for interface in interfaces {
for data in interface.iPv4Addresses {
if let ipv4 = IPv4Address(data) {
ipAddresses.append(String(describing: ipv4))
}
}
for data in interface.iPv6Addresses {
if let ipv6 = IPv6Address(data) {
ipAddresses.append(String(describing: ipv6))
}
}
}
return ipAddresses
}
ตรวจสอบการกำหนดเส้นทางเครือข่ายของลักษณะ
นอกจากนี้ คุณยังดูสถานที่ตั้งของลักษณะใน 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 ที่อัปเดตแล้วซึ่งส่งคืน
ระบบจะตัดชื่อหากเกินขีดจำกัด 60 Code Point ของ Unicode (อักขระ) และจะไม่มีข้อผิดพลาด นักพัฒนาแอปมีหน้าที่จัดการชื่อที่ยาว และสามารถตัดสินใจได้ว่าจะแจ้งให้ผู้ใช้ทราบว่าระบบจะตัดชื่อให้สั้นลงหรือไม่