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

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

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

import GoogleHomeSDK
import GoogleHomeTypes

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

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

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

// 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")
}

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

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

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

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

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

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

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

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

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

offWithEffect

// Turn off the light using the DyingLight effect.
do {
  try await onOffTraitTest.offWithEffect(
    effectIdentifier: Matter.OnOffTrait.EffectIdentifierEnum.dyingLight,
    effectVariant: 0
  )
} catch let _ as HomeError {
  // Code for handling the exception
}

moveToLevel

// 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 _ as HomeError {
  // Code for handling the exception
}

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

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

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

// 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!")
}

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

// 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 \(String(describing: onOffTrait.attributes.startUpOnOff))"
      )
    }
  }
}

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

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

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

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

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

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

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

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

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

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

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

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

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

לדוגמה:

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