אפשר לגשת לממשקי API של מכשירים דרך ממשקי ה-API של Home ל-iOS. מייבאים את החבילות הבאות לאפליקציה:
import GoogleHomeSDK
import GoogleHomeTypes
מידע נוסף זמין במאמר בנושא מודל הנתונים ב-iOS.
טיפול בשגיאות
חלק מהשיטות ב-Home APIs מחזירות 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).
הם גם מתחשבים בהתנגשויות של מאפיינים במקרה של מכשיר עם שני סוגי מכשירים, שלשניהם יכול להיות אותו מאפיין. לדוגמה, אם מכשיר הוא גם רמקול וגם מנורה עם אפשרות לעמעום, הוא יכלול שתי תכונות של הפעלה/השבתה ושתי תכונות של שליטה ברמה.
סוג נוסף של התנגשות מאפיינים יכול להתרחש כשבמכשיר יש שני מאפיינים עם אותו שם. לדוגמה, onOff
יכול להתייחס למופע של מאפיין OnOff
רגיל, או למופע של מאפיין OnOff
שהוגדר על ידי היצרן. כדי למנוע אי בהירות לגבי התכונה הרצויה, צריך להפנות לתכונה דרך אחת משתי קבוצות התכונות בכל סוג מכשיר.
למאפיינים רגילים, כלומר מאפיינים שדומים לאשכולות רגילים של Matter, משתמשים ב-matterTraits
. לדוגמה,
כדי לקבל מאפיין ספציפי לסוג המכשיר Dimmable Light (אור ניתן לעמעום):
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
מהתכונה On/Off (הפעלה/השבתה) של המכשיר:
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 }
קבלת רשימה של מכשירים עם תכונה ספציפית
כדי לקבל רשימה של מכשירים עם מאפיין ספציפי, צריך לבצע איטרציה על המכשירים, על סוגי המכשירים של כל מכשיר ועל המאפיינים של כל סוג מכשיר. לדוגמה, כדי לקבל רשימה של מכשירים בבית שיש להם את המאפיין On/Off (הפעלה/הפסקה):
// 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) } } }
רשימה מלאה של התכונות שזמינות בממשקי ה-API של Home מופיעה במאמר אינדקס התכונות ב-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) }
בממשקי ה-API של Home יש כמה סוגי מכשירים שיכולים לייצג סוג מכשיר ליבה. לדוגמה, אין סוג מכשיר 'קל'. במקום זאת, יש ארבעה סוגים שונים של מכשירים שיכולים לייצג אור, כפי שמוצג בדוגמה הקודמת. לכן, כדי לקבל תמונה מקיפה של סוג מכשיר ברמה גבוהה יותר בבית, צריך לכלול כמה סוגי מכשירים.
כאן מופיעה רשימה מלאה של סוגי המכשירים והתכונות שלהם שזמינים בממשקי ה-API של Home.
איך מקבלים את שם הספק, מזהה הספק או מזהה המוצר של מכשיר
מאפיין 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
.
מטא-נתונים של מכשירים ומאפיינים
למכשירים ולמאפיינים בממשקי ה-API של Home יש מטא-נתונים שמשויכים אליהם, שיכולים לעזור בניהול חוויית המשתמש באפליקציה.
כל מאפיין בממשקי ה-API של Home מכיל מאפיין sourceConnectivity
, שכולל מידע על הסטטוס אונליין של המאפיין ועל המיקום שלו (ניתוב מקומי או מרחוק).
קבלת הסוג הראשי של מכשיר
יכול להיות שבמכשירים מסוימים יוצגו כמה סוגים של מכשירים דרך ממשקי ה-API של Home. כדי לוודא שמשתמשים יראו באפליקציה את האפשרויות המתאימות למכשירים שלהם (כמו שליטה במכשיר והצעות לאוטומציות), כדאי לבדוק אם סוג המכשיר הוא הסוג העיקרי של המכשיר.
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 יכול להיות שמאפיינים רגילים עדיין יהיו אונליין בגלל ניתוב מקומי, אבל מאפיינים מבוססי-ענן יהיו אופליין.
בדיקת ניתוב הרשת של מאפיין
הלוקאל של מאפיין זמין גם בממשקי ה-API של Home. הסמל 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 תווים יחתכו, ולא יוצגו שגיאות. המפתחים אחראים לטיפול בשמות ארוכים. לדוגמה, הם יכולים להחליט אם הם רוצים להודיע למשתמשים שהשמות יקוצרו.
רשימת ממשקי API
אחרי שיוצרים מופע של Home
, אפשר לגשת דרכו לממשקי ה-API הבאים של המכשיר:
API | תיאור |
---|---|
device(id:) |
מחזירה Publisher למכשיר שצוין, שפולט את מצב המכשיר בכל פעם שהוא משתנה. |
devices() |
לקבל את כל המכשירים בכל המבנים בחשבון Google. הפונקציה מחזירה Query<HomeDevice> שמספק אפשרויות נוספות לאחזור ולסינון. |
אחרי שיש לכם HomeDevice
, תוכלו לגשת לממשקי ה-API הבאים דרכו:
API | תיאור |
---|---|
id |
המזהה הייחודי של המכשיר במערכת. |
name |
השם שהמשתמש נתן למכשיר. |
structureID |
המזהה של המבנה שהמכשיר משויך אליו. הפונקציה מחזירה String? . |
roomID |
המזהה של החדר שהמכשיר מוקצה לו. הפונקציה מחזירה String? . |
types |
קבלת סוג ספציפי או כל הסוגים שזמינים במכשיר. |
isMatterDevice |
אם המכשיר מגובה על ידי Matter. |
sourceConnectivity |
קישוריות המקור של המכשיר, שמייצגת מצבי קישוריות מצטברים ומיקום ברשת של מאפייני המכשיר. |