تشغيل جسر Matter مع Apple Home باستخدام حاسوب وهاتف فقط
قبل وصول العتاد: حاسوب Windows يؤدي دور البوابة وهاتف عليه nRF Connect يؤدي دور جهاز Bluetooth، مع الإقران والتحكم ومزامنة الحالة في Apple Home.
تناولت التدوينة السابقة الخطة العامة: وضع بوابة Matter بين أجهزتنا العاملة بالبلوتوث وتطبيق Apple Home، لتترجم الرسائل في الاتجاهين.
الخطط تبدو دائمًا مرتبة على الورق. وقبل أن ألمس أي قطعة عتاد، أردت أن أتأكد من أمر واحد أولًا: هل سيقبل Apple Home فعلًا بوابة كتبناها بأنفسنا، ويتحكم في أجهزة البلوتوث التي خلفها؟
هذا السؤال لا يحتاج إلى عتاد. فلوحات التطوير كانت لا تزال في طريقها إليّ، فاستعنت بما على مكتبي أصلًا: حاسوب بنظام Windows وهاتف، وشغّلت السلسلة كاملة من أولها إلى آخرها.
البرمجيات أولًا، والعتاد ثانيًا
في مشاريع العتاد يغريك أن تبدأ بشراء اللوحات ولحام الوحدات وتحميل البرامج الثابتة. المشكلة أن السلسلة حين تطول يصعب معرفة الطبقة التي تعطّلت: هل فشل اقتران Matter؟ أم في البوابة خطأ برمجي؟ أم فقد الاتصال التسلسلي بعض البايتات؟ أم أن إشارة البلوتوث ضعيفة ببساطة؟
إذا شغّلنا الطبقتين العلويتين بالبرمجيات أولًا، ضاقت دائرة البحث عند وصول العتاد الحقيقي. والتكلفة شبه معدومة: حاسوب وهاتف يكفيان.
من يلعب أي دور
| الدور | في المنتج الحقيقي | في هذا العرض التجريبي |
|---|---|---|
| المتحكّم | Apple Home | Apple Home (الحقيقي) |
| البوابة | لوحة Linux + وحدة بلوتوث | حاسوب Windows يستخدم البلوتوث المدمج فيه |
| جهاز البلوتوث | مفاتيح ومصابيح | هاتف يشغّل nRF Connect |
Apple Home حقيقي، وبرنامج البوابة هو نفسه الذي سيُشحن مع المنتج. الجهاز الوحيد الذي يؤدي دوره الهاتف هو جهاز البلوتوث في الأسفل.
nRF Connect تطبيق مجاني من Nordic لتنقيح أخطاء البلوتوث على Android وiPhone. يستطيع مسح إعلانات البلوتوث القريبة وبثّ إعلانات من عنده، وهذا يجعله بديلًا ممتازًا عن الجهاز الحقيقي.
لماذا لا نحاكي جهاز Bluetooth Mesh مباشرة؟
في المنتج الحقيقي تتحدث الأجهزة مع البوابة عبر SIG Mesh. لكن الهاتف لا يستطيع أداء دور جهاز Mesh: فلا Android ولا iOS يسمحان للتطبيقات بأن تصبح عقدة في شبكة Mesh. وتطبيقات مثل nRF Mesh لا تستطيع إلا تهيئة الأجهزة (provisioning) والعمل كجهاز تحكم عن بُعد.
لذلك يعتمد العرض التجريبي أسلوبًا أبسط: الجهاز والبوابة يتبادلان إعلانات بلوتوث عادية. لتشغيل مصباح، تبثّ البوابة رسالة “تشغيل”؛ وحين تتغير حالة الجهاز، يبثّ هو رسالة بذلك إلى البوابة.
هذا الشكل بلا تشفير وبلا حماية من إعادة الإرسال. وُجد فقط لاختبار السلسلة، ولن يُشحن أبدًا. قيمته أن كل ما في البوابة، عدا طبقة الاتصال الدنيا، حقيقي: اقتران Matter، وجدول الأجهزة، وترجمة الأوامر، ومزامنة الحالة.
صيغة الإعلان في العرض التجريبي
كلما كانت الصيغة أبسط كان ذلك أفضل: ينبغي أن تستطيع كتابتها يدويًا في تطبيق على الهاتف.
من البوابة إلى الجهاز (الاتجاه النازل): عنصر واحد من Manufacturer Data بمعرّف الشركة 0xFFFF. هذا المعرّف محجوز من Bluetooth SIG للاختبار، ولا يجوز استخدامه في منتجات حقيقية.
| البايتات | المحتوى | مثال |
|---|---|---|
| 1–2 | القيمة الثابتة GW |
47 57 |
| 3–4 | عنوان الجهاز، بترتيب little-endian | 02 00 تعني 0002 |
| 5 | حالة التشغيل/الإيقاف | 01 تشغيل، 00 إيقاف |
| 6 | رقم تسلسلي يزيد بمقدار 1 في كل مرة | 05 |
من الجهاز إلى البوابة (الاتجاه الصاعد): صيغة لـ Android وأخرى لـ iPhone.
- Android: أيضًا Manufacturer Data بمعرّف الشركة
0xFFFFوالبيانات4456020001. فـ4456هيDV، و0200هو العنوان 0002، والبايت الأخير01يعني تشغيل. - iPhone: لا يسمح iOS للتطبيقات بوضع بيانات مصنّع مخصصة في الإعلانات، بل بتغيير اسم الجهاز فقط. لذا نضبط الاسم على
DV0002:1، أي العنوان 0002 والحالة تشغيل.
تحليل الرسالة في جهة البوابة لا يحتاج إلا بضعة أسطر، ويقبل الصيغتين معًا:
pub fn uplink(sections: &[(u8, Vec<u8>)]) -> Option<(u16, bool)> {
sections.iter().find_map(|(t, d)| match (*t, d.as_slice()) {
// Android: manufacturer data FF FF 'D' 'V' address state
(0xFF, [0xFF, 0xFF, b'D', b'V', a0, a1, on, ..]) => {
Some((u16::from_le_bytes([*a0, *a1]), *on != 0))
}
// iPhone: device name DV0002:1
(0x08 | 0x09, name) => {
let s = std::str::from_utf8(name).ok()?.strip_prefix("DV")?;
let (addr, on) = s.split_once(':')?;
Some((u16::from_str_radix(addr, 16).ok()?, match on {
"1" => true,
"0" => false,
_ => return None,
}))
}
_ => None,
})
}
برنامج البوابة
كُتبت البوابة بلغة Rust، مع استخدام المكتبة مفتوحة المصدر rs-matter لتنفيذ Matter. ويعمل البلوتوث على الحاسوب عبر واجهات البلوتوث المدمجة في Windows، فلا حاجة إلى أي تعريفات إضافية.
عند التشغيل يؤدي البرنامج ثلاث مهام:
- يعمل كبوابة Matter: يعلن عن نفسه على الشبكة المحلية وينتظر اقتران Apple Home به. وإن لم يكن مقترنًا بعد، يُطبع رمز QR الخاص بالاقتران مباشرة في الطرفية.
- يحتفظ بجدول للأجهزة: بكتابة
add 0002 Living room lightفي الطرفية يُضاف مصباح. ويظهر كل جهاز في Matter بوصفه جهازًا جسريًا (bridged) مستقلًا. - يرسل الإعلانات ويستقبلها: أوامر Apple Home تتحول إلى إعلانات نازلة؛ وإعلانات الهاتف الصاعدة تحدّث الحالة، ثم تُزامَن مع Apple Home.
يُحفظ جدول الأجهزة وبيانات الاقتران في ملفات محلية، فلا يحتاج البرنامج إلى اقتران جديد عند إعادة تشغيله.
الإضافة إلى Apple Home
امسح رمز QR الظاهر في الطرفية بتطبيق Home على iPhone. وهناك بعض الأمور التي ينبغي الانتباه لها:
- ستظهر لك رسالة تحذير (“Uncertified Accessory”، أي “ملحق غير معتمد”). أثناء التطوير تستخدم البوابة شهادات Matter الاختبارية الرسمية، وهي غير معتمدة، ولذلك يحذّرك iOS. اختر (“Add Anyway”، أي “إضافة على أي حال”). أما الوحدات التجارية فتحتاج إلى شهادات حقيقية تُصدر بعد الاعتماد.
- يجب أن يكون الحاسوب وiPhone على الشبكة المحلية نفسها، ويجب أن يسمح جدار حماية Windows للبرنامج بإرسال حركة الشبكة واستقبالها. إذا انتهت مهلة الاقتران، فابدأ بفحص هذه النقطة.
- تحتاج إلى مركز منزلي (home hub). يتطلب Apple Home وجود HomePod أو Apple TV بوصفه مركزًا منزليًا للتحكم في ملحقات Matter.
بعد الإضافة يعرض Apple Home بوابة يقف خلفها “Living room light” و“Study light”، ويمكن وضع كل منهما في غرفة مختلفة كأي مصباح آخر.
الاتجاه النازل: تشغيل مصباح من Apple Home
- افتح nRF Connect على الهاتف وانتقل إلى تبويب Scanner.
- اضغط على مصباح غرفة المعيشة (“Living room light”) في Apple Home.
- تطبع طرفية الحاسوب
BLE TX -> 0002، وتبثّ البوابة الأمر لمدة ثانية واحدة. - يظهر جهاز جديد في قائمة المسح في nRF Connect ببيانات المصنّع
0xFFFFو4757 0200 01 xx، وهي تُقرأ هكذا: “البوابة تقول: الجهاز 0002، تشغيل”.
قد يستخدم الحاسوب عنوان بلوتوث مختلفًا في كل إعلان. وإن صعب عليك إيجاده في القائمة، فصفِّ حسب بيانات المصنّع أو قوة الإشارة.
الاتجاه الصاعد: الجهاز يُخبر Apple Home
- في nRF Connect أنشئ إعلانًا جديدًا (Advertiser). على Android أدخل بيانات المصنّع
0xFFFF/4456020001؛ وعلى iPhone اضبط اسم الجهاز علىDV0002:1. - ابدأ البثّ.
- تطبع طرفية الحاسوب
BLE RX <- 0002 (Living room light): ON. - يظهر مصباح غرفة المعيشة مضاءً في Apple Home.
هذا يحاكي شخصًا يضغط المفتاح على الجدار. وهو أهم من الاتجاه النازل: فإن لم تستطع حالة الجهاز العودة، فلن يطابق ما يعرضه Apple Home الواقع.
عثرات في الطريق
لا شيء من هذا معقد، لكن هناك مواضع يسهل التعثر فيها أول مرة.
1. إعلان الهاتف أعاد تشغيل المصابيح. يظل الهاتف يكرر الحزمة نفسها. في البداية كانت البوابة تحدّث الحالة كلما استقبلت حزمة، فبعد إطفاء مصباح من Apple Home كانت حزمة “التشغيل” القادمة من الهاتف تعيده بعد ثانية. الحل كان اعتبار التقرير جديدًا فقط عندما يتغير محتواه. والأجهزة الحقيقية تحتاج إلى الشيء نفسه: يجب إزالة تكرار الرسائل.
2. يضع iPhone اسم الجهاز في scan response. حين يبثّ iPhone إعلانًا، لا يكون اسم الجهاز في حزمة الإعلان الأولى بل في استجابة المسح (scan response). والمسح السلبي الافتراضي على الحاسوب لا يراه أبدًا؛ لا بد من المسح النشط.
3. لا يمكن تحديد الأجهزة بعنوان البلوتوث. تبثّ الهواتف والحواسيب بعناوين عشوائية تتغير دوريًا. لذلك وُضعت هوية الجهاز داخل الإعلان نفسه، في بايتَي العنوان. وهذا يوافق طريقة عمل Mesh: تُعرَّف أجهزة Mesh بعنوان unicast المسند إليها، لا بعنوان MAC.
4. تعدد الإعلانات في وقت واحد يسبب تداخلًا على Windows. عند الضغط على عدة مصابيح تباعًا، أُرسلت عدة إعلانات في الوقت نفسه فكتب بعضها فوق بعض. وضعها في طابور، واحدًا بعد الآخر، حلّ المشكلة.
5. البثّ عطّل Matter. يجب أن يستمر كل إعلان على Windows لبعض الوقت. وعند استدعائه مباشرة داخل حلقة المعالجة في Matter، كانت كل أوامر Apple Home الأخرى تنتظر طوال تلك المدة. لذا نُقل البثّ إلى خيط (thread) خاص به.
6. تغيير الشركة المصنّعة والطراز للبوابة لا يتطلب إعادة اقتران. يقرأ Apple Home هاتين القيمتين من البوابة ويلتقط القيم الجديدة بعد إعادة التشغيل. لكنه يخزّنهما مؤقتًا، ولا يمكن معرفة متى يحدّثهما. إن أردت رؤية التغيير فورًا، فاحذف البوابة وأعد إضافتها، لكن انتبه إلى أن حذف البوابة يحذف معها كل الأجهزة التي خلفها.
وإضافة إلى ذلك، كان البرنامج المترجَم حديثًا كبيرًا نسبيًا في البداية. وبعد التحسين للحجم وإزالة رموز التنقيح، يبلغ حجم النسخة النهائية نحو 2.3 MB، وهو يتسع بسهولة على لوحة بوابة.
ما الذي أثبته العرض التجريبي
ما ثبت:
- أن Apple Home يتعرّف على بوابة كتبناها بأنفسنا ويقترن بها.
- أن الأجهزة الجسرية يمكن التحكم فيها فرديًا في Apple Home.
- أن الأوامر النازلة والحالة الصاعدة تعملان معًا.
- أنه بعد إضافة الأجهزة أو إزالتها، أو إعادة التشغيل عقب انقطاع الاتصال، يبقى Apple Home متزامنًا.
ما لم يثبت بعد:
- تهيئة Bluetooth Mesh الحقيقية وتشفيرها وتكوين شبكتها.
- هل تعمل وحدة Silicon Labs مع أجهزة Telink معًا.
- كيف يعمل كل ذلك على لوحة بوابة Linux.
- السلوك عند اتصال عشرات الأجهزة أو مئاتها في وقت واحد.
بعبارة أخرى، نصف Matter تم التحقق منه؛ أما نصف Bluetooth Mesh فعليه أن ينتظر العتاد الحقيقي. الخطوة التالية هي استبدال إعلانات الحاسوب العادية بوحدة بلوتوث متصلة عبر منفذ تسلسلي. وفي برنامج البوابة، هذا مجرد طبقة محوّل (adapter) مختلفة.
كلمة أخيرة
أكبر مكسب من هذه الخطوة كان التأكد من أهم شيء قبل إنفاق المال على العتاد: Apple Home يقبل هذه البوابة. ومهما حدث من أعطال لاحقًا، لم تعد طبقة Matter موضع شك.
إن كنت تبني بوابة مشابهة، أو تريد تشغيل Matter قبل أن يتوفر لديك العتاد، فيسعدني أن نتحدث. تفاصيل الشيفرة والدروس المستفادة كلها مطروحة للنقاش: linktr.ee/weiyii
أعمل حاليًا على تنظيف شيفرة العرض التجريبي لإصدار نسخة أصغر منها مفتوحة المصدر. وسأضيف الرابط إلى هذه التدوينة حين تصدر.