คุณสามารถเข้าถึง 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 ที่แสดงสถานะปัจจุบันของ Home พร้อมการเปลี่ยนแปลงข้อมูลเมตาของอุปกรณ์ทุกรายการ หรือเรียกใช้
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
trait มีข้อมูล เช่น รหัสผู้ให้บริการ รหัสสินค้า ชื่อสินค้า และ
หมายเลขซีเรียลของอุปกรณ์
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
ลักษณะบางอย่าง โดยปกติแล้วจะเป็นลักษณะ smart home ของ Google อาจแสดงเป็น ออฟไลน์หากอุปกรณ์ไม่มีการเชื่อมต่ออินเทอร์เน็ต เนื่องจากลักษณะเหล่านี้ทำงานบนระบบคลาวด์และไม่มีการกำหนดเส้นทางในเครื่อง
ตรวจสอบการเชื่อมต่อของอุปกรณ์
ระบบจะตรวจสอบการเชื่อมต่อของอุปกรณ์ที่ระดับประเภทอุปกรณ์ เนื่องจากอุปกรณ์บางเครื่องรองรับประเภทอุปกรณ์หลายประเภท สถานะที่แสดงผลเป็นการรวมสถานะการเชื่อมต่อของลักษณะทั้งหมดในอุปกรณ์นั้น
let lightConnectivity = dimmableLightDeviceType.metadata.sourceConnectivity .connectivityState
คุณอาจเห็นสถานะ partiallyOnline ในกรณีที่อุปกรณ์มีประเภทผสมกันเมื่อไม่มีการเชื่อมต่ออินเทอร์เน็ต Matterลักษณะมาตรฐาน
ของ Matter อาจยังคงออนไลน์อยู่เนื่องจากการกำหนดเส้นทางในเครื่อง แต่ลักษณะที่ทำงานบนระบบคลาวด์จะ
ออฟไลน์
รับที่อยู่ IP ของอุปกรณ์
หากต้องการค้นหาที่อยู่ IP ของอุปกรณ์ ให้ใช้แอตทริบิวต์ networkInterfaces ของ
the
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 เดิมจะยังคงเหมือนเดิม และการเปลี่ยนแปลงจะแสดงในออบเจ็กต์ HomeDevice ที่อัปเดตซึ่งแสดงผล
ระบบจะตัดชื่อให้สั้นลงหากยาวเกินขีดจำกัด 60 Code Point ของ Unicode (อักขระ) และจะไม่แสดงข้อผิดพลาด นักพัฒนาแอปมีหน้าที่จัดการชื่อที่ยาว และสามารถตัดสินใจได้ว่าจะแจ้งให้ผู้ใช้ทราบว่าระบบจะตัดชื่อให้สั้นลงหรือไม่