שליטה במכשירים ב-iOS

המדריך הזה ממשיך את המדריך גישה למכשירים ולמטא-נתונים של מכשירים ב-iOS, ומציג דוגמאות נוספות לשליטה במכשירים ולגישה אליהם.

כדי להשתמש בסוגים או במאפיינים ספציפיים של מכשירים, כמו Matter OnOffTrait שנעשה בהם שימוש בדוגמאות רבות כאן, צריך לייבא אותם:

import GoogleHomeSDK
import GoogleHomeTypes

בדיקה אם מאפיין תומך בפקודה

כדי לבדוק אם פקודה מסוימת נתמכת במכשיר מסוים, משתמשים בפונקציה supports ברמת המאפיין.

לדוגמה, כדי לבדוק אם מכשיר תומך בפקודה toggle של המאפיין On/Off:

// Check if the OnOff trait supports the toggle command.
if onOffTraitTest.supportsToggleCommand {
  print("onOffTrait supports toggle command")
} else {
  print("onOffTrait does not support stateful toggle command")
}

שליחת פקודה למכשיר

שליחת פקודה דומה לקריאת מאפיין מצב ממאפיין. כדי להפעיל או להשבית את המכשיר, משתמשים בפקודה OnOffTrait Toggle, שמוגדרת במודל הנתונים של הסביבה העסקית של Google Home בתור toggle(). השיטה הזו משנה את הערך של onOff ל-false אם הוא true, או ל-true אם הוא false:

// Calling a command on a trait.
do {
  try await onOffTraitTest.toggle()
} catch let error as HomeError {
  // Code for handling the exception
}

אם תזוהה בעיה בתהליך הביצוע, הפקודות עשויות להחזיר חריגה. כמפתחים, כדאי להשתמש בבלוק do-catch כדי לטפל כראוי בחריגות האלה, ולהציג למשתמשים מידע מפורט במקרים שבהם אפשר לבצע פעולה כלשהי בעקבות השגיאות. חריגות שלא מטופלות יעצרו את סביבת זמן הריצה של האפליקציה, ויכול להיות שיגרמו לקריסות באפליקציה.

לחלופין, אפשר להשתמש בפקודות off() או on() כדי להגדיר את המצב במפורש:

do {
  try await onOffTraitTest.off()
  try await onOffTraitTest.on()
} catch let error as HomeError {
  // Code for handling the exception
}

אחרי שליחת הפקודה לשינוי המצב, כשהיא תושלם תוכלו לקרוא את המצב כפי שמתואר בקטע קריאת המצב של המכשיר כדי לטפל בו באפליקציה.

שליחת פקודה עם פרמטרים

בפקודות מסוימות יכולים להופיע פרמטרים, כמו אלה שמופיעים ב-OnOffTrait או ב-LevelControlTrait:

// Turn off the light using the DyingLight effect.
do {
  try await onOffTraitTest.offWithEffect(
    effectIdentifier: Matter.OnOffTrait.EffectIdentifierEnum.dyingLight,
    effectVariant: 0
  )
} catch let error as HomeError {
  // Code for handling the exception
}
// Change the brightness of the light to 50%
do {
  try await levelControlTraitTest.moveToLevel(
    level: UInt8(127),
    transitionTime: 0,
    optionsMask: Matter.LevelControlTrait.OptionsBitmap(),
    optionsOverride: Matter.LevelControlTrait.OptionsBitmap()
  )
} catch let error as HomeError {
  // Code for handling the exception
}

בדיקה אם מאפיין תומך במאפיין

יכול להיות שחלק מהמכשירים יתמכו במאפיין Matter, אבל לא במאפיין ספציפי. לדוגמה, יכול להיות שמכשיר Cloud-to-cloud שתואם ל-Matter לא תומך בכל המאפיינים של Matter. כדי לטפל במקרים כאלה, אפשר להשתמש במאפיין isSupported ברמת המאפיין כדי לבדוק אם המאפיין נתמך במכשיר מסוים.

לדוגמה, כדי לבדוק אם מכשיר תומך במאפיין onOff של המאפיין מצב מופעל/מושבת:

// Check if the OnOff trait supports the onOff attribute.
if onOffTrait.attributes.$onOff.isSupported {
  print("onOffTrait supports onOff state")
} else {
  print("onOffTrait is for a command only device!")
}

חלק מהמאפיינים יכולים להיות ריקים במפרט Matter או בסכמה Cloud-to-cloud smart home. במאפיינים האלה, אפשר להשתמש ב-isNullable בנוסף ל-isSupported כדי לקבוע אם הערך nil שהמאפיין מחזיר הוא בגלל שהמכשיר לא מדווח על הערך הזה, או אם הערך של המאפיין הוא באמת nil:

// Check if a nullable attribute is set or is not supported.
if let deviceType = await device.types.get(OnOffLightDeviceType.self) {
  if let onOffTrait = deviceType.traits[Matter.OnOffTrait.self] {
    if onOffTrait.attributes.startUpOnOff == nil {
      if onOffTrait.attributes.$startUpOnOff.isSupported {
        print(
          "onOffTrait supports startUpOnOff and it is nil. Check the spec for the contextual meaning."
        )
      } else {
        print("onOffTrait does not support startUpOnOff!")
      }
    } else {
      print(
        "onOffTrait supports startUpOnOff and it is set to \(onOffTrait.attributes.startUpOnOff)"
      )
    }
  }
}

עדכון מאפייני המאפיינים

אם אתם רוצים לשנות את הערך של מאפיין נתון ואף אחת מהפקודות של המאפיין לא עושה זאת, יכול להיות שהמאפיין תומך בהגדרת הערך שלו באופן מפורש.

האפשרות לשנות את הערך של מאפיין תלויה בשני גורמים:

  • האם אפשר לכתוב במאפיין?
  • האם הערך של המאפיין יכול להשתנות כתוצאה משליחת פקודה של מאפיין?

המידע הזה מופיע במסמכי העזר של המאפיינים והמאפיינים שלהם.

לכן, השילובים של המאפיינים שקובעים איך אפשר לשנות את הערך של מאפיין הם:

  • לקריאה בלבד ולא מושפעת מפקודות אחרות. כלומר, הערך של המאפיין לא משתנה. לדוגמה, המאפיין currentPosition של SwitchTrait.

  • לקריאה בלבד ומושפעת מפקודות אחרות. המשמעות היא שהערך של המאפיין יכול להשתנות רק כתוצאה משליחת פקודה. לדוגמה, המאפיין currentLevel של LevelControlTrait הוא לקריאה בלבד, אבל אפשר לשנות את הערך שלו באמצעות פקודות כמו moveToLevel.

  • ניתן לכתוב בהן והן לא מושפעות מפקודות אחרות. כלומר, אפשר לשנות ישירות את הערך של המאפיין באמצעות הפונקציה update של המאפיין, אבל אין פקודות שמשפיעות על הערך של המאפיין. לדוגמה, המאפיין WrongCodeEntryLimit של DoorLockTrait.

  • ניתן לכתוב בהן והן מושפעות מפקודות אחרות. המשמעות היא שאפשר לשנות את הערך של המאפיין ישירות באמצעות הפונקציה update של המאפיין, והערך של המאפיין יכול להשתנות כתוצאה משליחת פקודה. לדוגמה, אפשר לכתוב למאפיין occupiedCoolingSetpoint של ThermostatTrait, אבל אפשר גם לעדכן אותו באמצעות הפקודה setpointRaiseLower.

דוגמה לשימוש בפונקציית update כדי לשנות את הערך של מאפיין

בדוגמה הזו מוסבר איך להגדיר באופן מפורש את הערך של המאפיין DoorLockTrait.wrongCodeEntryLimit.

כדי להגדיר ערך למאפיין, צריך לקרוא לפונקציית update של המאפיין ולהעביר לה פונקציית עדכון שמגדירה את הערך החדש. מומלץ קודם לוודא שהמאפיין תומך במאפיין.

לדוגמה:

if doorLockTraitTest.attributes.$wrongCodeEntryLimit.isSupported {
  let _ = try await doorLockTraitTest.update {
    $0.setWrongCodeEntryLimit(3)
  }
}