איך בודקים אם מאפיין תומך בפקודה
אפשר גם לבדוק אם יש תמיכה בפקודה של מאפיין. אפשר גם להשתמש בפונקציה supports
ברמת המאפיין כדי לבדוק אם יש תמיכה בפקודה במכשיר מסוים.
לדוגמה, כדי לבדוק אם מכשיר תומך בפקודה toggle
של המאפיין On/Off:
// Check if the OnOff trait supports the toggle command. if (onOffTrait.supports(OnOff.Command.Toggle)) { println("onOffTrait supports toggle command") } else { println("onOffTrait does not support stateful toggle command") }
שליחת פקודה למכשיר
שליחת פקודה דומה לקריאת מאפיין מצב ממאפיין. כדי להפעיל או להשבית את המכשיר, משתמשים בפקודה Toggle של המאפיין OnOff
, שמוגדר במודל הנתונים של הסביבה העסקית של Google Home בתור toggle()
. השיטה הזו משנה את הערך של onOff
ל-false
אם הוא true
, או ל-true
אם הוא false
:
// Calling a command on a trait. try { onOffTrait.toggle() } catch (e: HomeException) { // Code for handling the exception }
כל הפקודות של המאפיינים הן פונקציות suspend
, והן מסתיימות רק כשה-API מחזיר תשובה (למשל אישור שהמצב של המכשיר השתנה).
אם תזוהה בעיה בתהליך הביצוע, הפקודות עשויות להחזיר חריגה. כמפתחים, כדאי להשתמש בבלוק try-catch
כדי לטפל כראוי בחריגות האלה, ולהציג למשתמשים מידע מפורט במקרים שבהם אפשר לבצע פעולה כלשהי בעקבות השגיאות. חריגות שלא מטופלות יעצרו את סביבת זמן הריצה של האפליקציה, ויכול להיות שיגרמו לקריסות באפליקציה.
לחלופין, אפשר להשתמש בפקודות off()
או on()
כדי להגדיר את המצב במפורש:
onOffTrait.off() onOffTrait.on()
אחרי שליחת הפקודה לשינוי המצב, כשהיא תושלם תוכלו לקרוא את המצב כפי שמתואר בקטע קריאת המצב של המכשיר כדי לטפל בו באפליקציה. לחלופין, תוכלו להשתמש בתהליכים כפי שמתואר בקטע מעקב אחרי המצב, שהיא השיטה המועדפת.
שליחת פקודה עם פרמטרים
בפקודות מסוימות יכולים להופיע פרמטרים, כמו אלה שמופיעים במאפיינים OnOff
או LevelControl
:
offWithEffect
// Turn off the light using the DyingLight effect. onOffTrait.offWithEffect( effectIdentifier = OnOffTrait.EffectIdentifierEnum.DyingLight, effectVariant = 0u, )
moveToLevel
// Change the brightness of the light to 50% levelControlTrait.moveToLevel( level = 127u.toUByte(), transitionTime = null, optionsMask = LevelControlTrait.OptionsBitmap(), optionsOverride = LevelControlTrait.OptionsBitmap(), )
לפקודות מסוימות יש ארגומנטים אופציונליים שמופיעים אחרי הארגומנטים הנדרשים.
לדוגמה, לפקודה step
של המאפיין FanControl
יש שני ארגומנטים אופציונליים:
val fanControlTraitFlow: Flow<FanControl?> = device.type(FanDevice).map { it.standardTraits.fanControl }.distinctUntilChanged() val fanControl = fanControlTraitFlow.firstOrNull() // Calling a command with optional parameters not set. fanControl?.step(direction = FanControlTrait.StepDirectionEnum.Increase) // Calling a command with optional parameters. fanControl?.step(direction = FanControlTrait.StepDirectionEnum.Increase) { wrap = true }
איך בודקים אם מאפיין תומך במאפיין
יכול להיות שחלק מהמכשירים יתמכו במאפיין Matter, אבל לא במאפיין ספציפי. לדוגמה, יכול להיות שמכשיר Cloud-to-cloud שתואם ל-Matter לא תומך בכל המאפיינים של Matter. כדי לטפל במקרים כאלה, צריך להשתמש בפונקציה supports
ברמת המאפיין וב-enum Attribute
של המאפיין כדי לבדוק אם יש תמיכה במאפיין במכשיר מסוים.
לדוגמה, כדי לבדוק אם מכשיר תומך במאפיין onOff
של המאפיין'מופעל/מושבת':
// Check if the OnOff trait supports the onOff attribute. if (onOffTrait.supports(OnOff.Attribute.onOff)) { println("onOffTrait supports onOff state") } else { println("onOffTrait is for a command only device!") }
חלק מהמאפיינים יכולים להיות ריקים במפרט Matter או בסכמה Cloud-to-cloud smart home. במאפיינים האלה, אפשר להשתמש ב-isNullable
בנוסף ל-supports
כדי לקבוע אם הערך null שהמאפיין מחזיר נובע מכך שהמכשיר לא מדווח על הערך הזה, או אם הערך של המאפיין הוא באמת null
:
// Check if a nullable attribute is set or is not supported. if (onOffTrait.supports(OnOff.Attribute.startUpOnOff)) { // The device supports startupOnOff, it is safe to expect this value in the trait. if (OnOff.Attribute.startUpOnOff.isNullable && onOffTrait.startUpOnOff == null) { // This value is nullable and set to null. Check the specification as to // what null in this case means println("onOffTrait supports startUpOnOff and it is null") } else { // This value is nullable and set to a value. println("onOffTrait supports startUpOnOff and it is set to ${onOffTrait.startUpOnOff}") } } else { println("onOffTrait does not support startUpOnOff!") }
עדכון מאפייני המאפיינים
אם אתם רוצים לשנות את הערך של מאפיין נתון ואף אחת מהפקודות של המאפיין לא עושה זאת, יכול להיות שהמאפיין תומך בהגדרת ערך מפורש.
האפשרות לשנות את הערך של מאפיין תלויה בשני גורמים:
- האם אפשר לכתוב במאפיין?
- האם הערך של המאפיין יכול להשתנות כתוצאה משליחת פקודה של מאפיין?
המידע הזה מופיע במסמכי העזרה לגבי המאפיינים והמאפיינים שלהם.
לכן, השילובים של המאפיינים שקובעים איך הערך של מאפיין יכול להשתנות הם:
לקריאה בלבד ולא מושפעת מפקודות אחרות. כלומר, הערך של המאפיין לא משתנה. לדוגמה, המאפיין
currentPosition
של המאפייןSwitch
.לקריאה בלבד ומושפעת מפקודות אחרות. המשמעות היא שהדרך היחידה שבה הערך של המאפיין יכול להשתנות היא כתוצאה משליחת פקודה. לדוגמה, המאפיין
currentLevel
של המאפיין Matter שלLevelControl
הוא לקריאה בלבד, אבל אפשר לשנות את הערך שלו באמצעות פקודות כמוmoveToLevel
.ניתן לכתוב בהן והן לא מושפעות מפקודות אחרות. כלומר, אפשר לשנות ישירות את הערך של המאפיין באמצעות הפונקציה
update
של המאפיין, אבל אין פקודות שמשפיעות על הערך של המאפיין. לדוגמה, המאפייןWrongCodeEntryLimit
של המאפייןDoorLock
.ניתן לכתוב בהן והן מושפעות מפקודות אחרות. כלומר, אפשר לשנות את הערך של המאפיין ישירות באמצעות הפונקציה
update
של המאפיין, והערך של המאפיין יכול להשתנות כתוצאה משליחת פקודה. לדוגמה, אפשר לכתוב במאפייןoccupiedCoolingSetpoint
של המאפייןThermostat
, אבל אפשר גם לעדכן אותו באמצעות הפקודהsetpointRaiseLower
.
דוגמה לשימוש בפונקציית update כדי לשנות את הערך של מאפיין
בדוגמה הזו מוסבר איך להגדיר באופן מפורש את הערך של המאפיין DoorLockTrait.WrongCodeEntryLimit
.
כדי להגדיר ערך למאפיין, קוראים לפונקציית update
של המאפיין ומעבירים לה פונקציית מוטאטור שמגדירה את הערך החדש.
מומלץ קודם לוודא שהמאפיין תומך במאפיין.
לדוגמה:
var doorLockDevice = home.devices().list().first { device -> device.has(DoorLock) } val traitFlow: Flow<DoorLock?> = doorLockDevice.type(DoorLockDevice).map { it.standardTraits.doorLock }.distinctUntilChanged() val doorLockTrait: DoorLock = traitFlow.first()!! if (doorLockTrait.supports(DoorLock.Attribute.wrongCodeEntryLimit)) { val unused = doorLockTrait.update { setWrongCodeEntryLimit(3u) } }