מעקב אחרי מצב המכשיר ב-Android

ב-Home APIs ל-Android, אפשר לעקוב אחרי שינויים במצב בבית באמצעות תהליכים ב-Kotlin. אפשר לעקוב אחרי שינויים במבנים, בחדרים, במטא-נתונים של המכשיר ובמצב המכשיר ב-Home APIs באמצעות כל ממשק API שעובר בירושה מממשק HomeObjectsFlow. כדי לעשות זאת, צריך לאסוף מהתהליך.

כשמוסיפים, מוחקים או משנים פריט כלשהו באוסף, המערכת מחזירה את קובץ snapshot העדכני ביותר של האוסף.

המפתח צריך להסיק את השינויים הספציפיים על ידי השוואה של קובץ snapshot הזה לעותק ישן יותר. אפשר להשתמש בשדה id שסופק לכל סוג של אובייקט הורה בממשקי Home API למטרה הזו.

איך משתמשים בתהליכים

בהמשך מפורטות כמה דוגמאות בסיסיות לאיסוף מנתונים בממשקי ה-API של Home. בדוגמאות הבאות, צריך ליצור מופע של Home לפני שמקבלים גישה לקולקציות בבית:

val context = LocalContext.current
val homeManager = Home.getClient(context)

מעקב אחר שינויים במבנה

השינויים הבאים במבנה מפעילים את האוסף הזה:

homeManager.structures().map { it.firstOrNull() }.collect {
  println("Structure ${it.id} updated to ${it}")
}

val structure =  homeManager.structures().list().firstOrNull()!!

מעקב אחר שינויים במכשיר ספציפי

השינויים הבאים במכשיר מפעילים את האוסף הזה:

structure
  .devices()
  .map { devices -> device.filter { it.name == "Bedroom Lamp" }.single() }
  .collect {
    println("The bedroom lamp has changed!")
  }

val device = structure.devices().list().firstOrNull { it.name == "Bedroom Lamp" }!!

מעקב אחר שינויים במאפיין ספציפי במכשיר

אפשר להשתמש בכל מאפיין שנתמך במכשיר ובממשקי ה-API של Home. הרשימה המלאה מופיעה במאמר Trait.

device.trait(OnOff).collect {
  if (it != null) {
    println("Got new state update! ${it.onOff}")
  }
}

מעקב אחר שינויים מסוג ספציפי במכשיר

השינויים הבאים בסוגי המכשירים מפעילים את האוסף הזה:

משתמשים בכל סוג של מכשיר Matter שנתמך ב-Home APIs. הרשימה המלאה מופיעה במאמר DeviceType.

device.type(DimmableLightDevice).collect { type ->
    println("Got new state update! ${type.trait(LevelControl)?.currentLevel}")
}

מעקב אחר שינויים בחדר במבנה

השינויים הבאים בחדר מפעילים את האוסף הזה:

כדי לעקוב אחרי הוספה או הסרה של מכשירים מהחדר, משתמשים בתהליך devices().

structure.rooms().collect {
  println("Got a new updated set of rooms!")

  for (room in it) {
    println("Got room $room")
  }
}

הרשמה לאירועים

ב-Home APIs, אירועים משמשים לזיהוי שינויים במצב של מכשיר.

כדי להירשם לאירועים במכשיר ספציפי, צריך להפעיל את אחת משלושת הפונקציות הבאות: HomeDevice.פונקציות events, שכל אחת מהן מחזירהFlow<Event>:

  1. הפונקציה events(event: EventFactory<T>) מחזירה תהליך לאירוע מסוג ספציפי:

    val eventFlow = homeDevice.type(DoorLockDevice).first().events(DoorLock.DoorLockAlarmEvent)
    
  2. הפונקציה events(trait: TraitFactory<T>) מחזירה את כל האירועים שנשלחו על ידי מאפיין:

    val eventflow = homeDevice.type(DoorLockDevice).first().events(DoorLock)
    
  3. הפונקציה events() מחזירה את האירועים הזמינים לאובייקט:

    val eventflow = homeDevice.type(DoorLockDevice).first().events()
    

כדי לצרוך אירועים מתהליך, משתמשים בפונקציה flow.collect():

eventflow.collect { event ->
  if (event != null) {
    logger.atInfo().log("Received event %s", event)
    // do something
  }
}

הרשמה לאירועים של יחסי ישויות

אפשר להאזין לאירועים שמתרחשים בכל פעם שמתווסף, מוסר או מתעדכן ישות (למשל מבנה, חדר, מכשיר או אוטומציה). האירועים האלה הם מופעים של HomeObjectChangeEvent, והם מכילים את המזהה של הישות שהשתנתה.

כדי לקבל מקור נתונים שיוצר את האירועים הרצויים, צריך להפעיל את השיטה stream() על HomeObjectsFlow<T> שנוצר על ידי שיטת Flow המתאימה:

טבלה: מקורות נתונים של אירועים
ישות ממשק שיטת Flow
Structure HasStructures structures()
Room HasRooms rooms()
HomeDevice HasHomeDevices devices()
Automation HasAutomations automations()

לדוגמה, כך אפשר לטפל בשינויים במכשירים:

val devicesStream = home.devices().stream()

// Collect and react to device changes.
devicesStream.collect { deviceEvent ->
  when (deviceEvent) {
    is HomeObjectAddedEvent ->
      println("New device now available with id: ${deviceEvent.id}")
    is HomeObjectUpdatedEvent -> println("Device ${deviceEvent.id} has been updated")
    is HomeObjectRemovedEvent -> println("Device is removed from your account")
    else -> {}
  }
}