تتكوّن بعض أجهزة "Matter" من عدة نقاط نهاية من نوع الجهاز نفسه. أما أجهزة Matter الأخرى، فهي هرمية، مع نقاط نهاية متداخلة داخل نقاط نهاية أخرى. في واجهات برمجة التطبيقات لمنزل Google، يُشار إلى كلا النوعَين من الأجهزة باسم الأجهزة المتعدّدة الأجزاء.
تمثيل مسطّح
قبل الإصدار 1.8 من واجهات برمجة التطبيقات لمنزل Google، يتم تمثيل الأجهزة المتعدّدة الأجزاء بواسطة واجهات برمجة التطبيقات لمنزل Google كمجموعة من الأجهزة المنفصلة وغير المرتبطة ببعضها. ويُشار إلى ذلك باسم التمثيل المسطّح.
على سبيل المثال، يظهر جهاز لوحة حائط واحد يتضمّن أربعة مفاتيح في Home APIs كأربعة أجهزة مختلفة وغير مرتبطة. ويمكن تمثيل جهاز Matter هرمي، مثل الثلاجة، في واجهات برمجة التطبيقات لمنزل Google كمجموعة من الأجهزة، يتوافق كل منها مع إحدى نقاط النهاية.
تمثيل مسطّح للوحة جدارية تتضمّن 4 مفاتيح
تمثيل مسطّح لثلاجة
تمثيل متعدد الأجزاء
بدءًا من الإصدار 1.8 من واجهات برمجة التطبيقات لمنزل Google، يمكن تمثيل الجهاز المتعدّد الأجزاء في واجهة برمجة التطبيقات كجهاز واحد. لتفعيل هذا السلوك، يمكنك استدعاء الطريقة devices() في Structure أو Room أو HomeManager وضبط المَعلمة enableMultipartDevices على true:
var multipartDevice = structure.devices(enableMultipartDevices = multipartEnabled) var multipartDevice = multipartDevices.list().filter{ device -> device.has(PowerStrip)}
توضّح المخطّطات البيانية التالية كيف يؤثر خيار enableMultipartDevices
في تمثيل جهاز متعدّد الأجزاء في Home APIs:
تمثيل متعدد الأجزاء للوحة حائط
تمثيل متعدد الأجزاء لثلاجة
يمكنك دائمًا الحصول على التمثيل المسطّح من خلال حذف المَعلمة enableMultipartDevices أو ضبطها على false.
التنقّل في جهاز متعدد الأجزاء
في الجهاز المتعدّد الأجزاء، يُطلق على كل مثيل مكوّن لنوع جهاز اسم جزء.
يمكن الوصول إلى الأجزاء مباشرةً إما على الجهاز الرئيسي أو على جزء بطريقة هرمية، باستخدام أنواع الأجهزة أو علامات Matter الدلالية. يتم تنفيذ العلامات الدلالية في Home APIs باستخدام
DescriptorTrait.SemanticTagStruct.
تنفّذ الفئة المجرّدة DeviceType واجهة HasParts، ما يتيح للمطوّرين التنقّل في شجرة الأجهزة من خلال السمة parts والطريقة part(). ينفّذ كل مثيل جزء أيضًا واجهة HasParts، بحيث يؤدي استدعاء parts() في جزء إلى إنشاء قائمة من صفر أو أكثر من الأجزاء الفرعية.
يوضّح المثال التالي كيفية الوصول إلى أجزاء جهاز التحكّم المتعدّد:
val device = homeManager .devices(enableMultipartDevices = true) .itemFlow(Id(MULTI_SWITCH_DEVICE)) .first() // Here at top-level, we are using the homeDevice.parts() API to access flow of // all the switches. Then we get the part ids. val partIds = device .parts() .map { parts -> parts.filter { it.has(Switch) }.mapNotNull { it.metadata.partId } } .first() .toSet()
يوضّح المثال التالي كيفية الوصول إلى أجزاء جهاز ثلاجة:
val rootDevice = homeManager.devices(true).itemFlow(Id("device@uuid1")) // On the top level, HomeDevice provides both plural (parts) // and singular (part) APIs. // The parts() API returns all the parts accessible from the top level, // including Endpoint 0 and its children. val childParts = rootDevice.parts().first() // childParts contain (EP0 as RootNode, EP1 as Refrigerator) // The singular part() API accepts DeviceType and tags (optional). val refrigerator = rootDevice.part(Refrigerator).first() // Get the refrigerator device which in this case is just device@uuid1 val refrigeratorDevice = homeManager.devices(false).itemFlow(refrigerator.metadata.partId.deviceId) // DeviceType uses a synchronous API for providing access to parts val cabinets = refrigerator.parts // [EP2, EP3] // Get the HomeDevice for these cabinets (device@uuid2 and device@uuid3) val cabinetDeviceIds = cabinets.map { it.metadata.partId } // Now use the devices API with enableMultipartDevices = false. val cabinetDevices = homeManager.devices(false) .map { devices -> devices.filter { it.id in cabinetDeviceIds } }.first()