คุณเข้าถึง Device API ได้ผ่าน Home API สำหรับ iOS นำเข้าแพ็กเกจต่อไปนี้ไปยังแอป
import GoogleHomeSDK
import GoogleHomeTypes
ดูข้อมูลเพิ่มเติมได้ที่โมเดลข้อมูลใน iOS
การจัดการข้อผิดพลาด
เมธอดบางรายการใน Home API จะแสดง HomeError ดังนั้นเราขอแนะนำให้คุณใช้บล็อก do-catch เพื่อตรวจจับ HomeError ในการเรียกใช้เหล่านั้น
เมื่อจัดการ HomeError ให้ตรวจสอบช่อง code และ message เพื่อดูว่าเกิดข้อผิดพลาดใดขึ้น
ข้อผิดพลาดที่ไม่ได้จัดการจะทำให้แอปขัดข้อง
ดูข้อมูลเพิ่มเติมได้ที่การจัดการข้อผิดพลาด
ดูตัวอย่างได้ที่หัวข้อส่งคำสั่งไปยังอุปกรณ์
ตัวอย่างการโทร
ดูรายการอุปกรณ์
เมื่ออ้างอิงออบเจ็กต์ Home ให้เรียกใช้ devices() เพื่อรับ Query ของอุปกรณ์ที่เข้าถึงได้
เรียกใช้เมธอด batched() ของ Query ซึ่งจะแสดง 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 ประเภทอาจมีลักษณะเดียวกัน ตัวอย่างเช่น หากอุปกรณ์เป็นทั้งลำโพงและหลอดไฟแบบหรี่แสงได้ อุปกรณ์จะมีลักษณะ On/Off 2 รายการและ Level Control 2 รายการ
การขัดแย้งของลักษณะอีกประเภทหนึ่งอาจเกิดขึ้นเมื่ออุปกรณ์มีลักษณะ 2 รายการที่มีชื่อเดียวกัน ตัวอย่างเช่น onOff อาจหมายถึงอินสแตนซ์ของลักษณะ OnOff มาตรฐาน หรืออาจหมายถึงอินสแตนซ์ของลักษณะ OnOff ที่ผู้ผลิตกำหนด เพื่อขจัดความคลุมเครือที่อาจเกิดขึ้นเกี่ยวกับลักษณะที่ต้องการ ให้อ้างอิงลักษณะผ่านคอลเล็กชันลักษณะ 1 ใน 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 มีอุปกรณ์หลายประเภทที่อาจแสดงถึงประเภทอุปกรณ์หลัก เช่น ไม่มีประเภทอุปกรณ์ "Light" แต่จะมีอุปกรณ์ 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 เพื่อระบุอุปกรณ์ 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 เดิมจะยังคงเหมือนเดิม และการเปลี่ยนแปลงจะแสดงในออบเจ็กต์ HomeDevice ที่อัปเดตซึ่งแสดงผล
ระบบจะตัดชื่อให้สั้นลงหากเกินขีดจำกัด Code Point (อักขระ) ของ Unicode ที่ 60 รายการ และจะไม่แสดงข้อผิดพลาด นักพัฒนาแอปมีหน้าที่รับผิดชอบในการจัดการชื่อที่ยาว และสามารถตัดสินใจได้ว่าต้องการแจ้งให้ผู้ใช้ทราบหรือไม่ว่าชื่อจะถูกตัดให้สั้นลง
ตรวจสอบการเป็นสมาชิกกลุ่มของอุปกรณ์
อุปกรณ์จริงสามารถอยู่ในกลุ่มอุปกรณ์ได้มากกว่า 1 กลุ่ม หากต้องการตรวจสอบว่าอุปกรณ์อยู่ในกลุ่มใด ให้ตรวจสอบ GroupMembershipTrait ในอุปกรณ์ โดยทำดังนี้
if let trait = await device.traits.get(Google.GroupMembershipTrait.self) {
for groupId in trait.attributes.groupObjectIdsArray {
print("Device belongs to group: \(groupId)")
}
}
หากต้องการตรวจสอบประเภทอุปกรณ์ที่ DeviceGroup รองรับและส่งคำสั่งไปยังกลุ่มเป็นเอนทิตีเดียว โปรดดูหัวข้อควบคุมกลุ่มอุปกรณ์