تفعيل التسليم المحلي عمليات الدمج من السحابة الإلكترونية إلى السحابة الإلكترونية

1. قبل البدء

تتيح عمليات الدمج مع الأجهزة المنزلية الذكية لـ "مساعد Google" التحكّم في الأجهزة المتصلة في منازل المستخدمين. لإنشاء عملية دمج من السحابة إلى السحابة، عليك تقديم نقطة نهاية لبرنامج ربط على السحابة الإلكترونية يمكنها التعامل مع طلبات المنزل الذكي. على سبيل المثال، عندما يقول المستخدم "Ok Google، أريد تشغيل الأضواء"، يرسل "مساعد Google" الأمر إلى خدمة التنفيذ المستندة إلى السحابة الإلكترونية لتعديل حالة الجهاز.

تعمل حزمة Local Home SDK على تحسين عملية الدمج بين "مساعد Google" والمنزل المزوّد بأجهزة ذكية من خلال إضافة مسار محلي لتوجيه الطلبات المتعلقة بالمنزل مباشرةً إلى جهاز Google Home، ما يؤدي إلى تحسين الموثوقية وتقليل وقت الاستجابة عند معالجة طلبات المستخدمين. تتيح لك كتابة تطبيق تنفيذ محلي ونشره بلغة TypeScript أو JavaScript، ويتيح هذا التطبيق تحديد الأجهزة وتنفيذ الأوامر على أي مكبّر صوت ذكي من Google Home أو شاشة ذكية من Google Nest. بعد ذلك، يتواصل تطبيقك مباشرةً مع الأجهزة الذكية الحالية للمستخدمين عبر شبكة المنطقة المحلية باستخدام البروتوكولات العادية الحالية لتنفيذ الأوامر.

72ffb320986092c.png

المتطلبات الأساسية

ما ستنشئه

في هذا الدرس العملي، ستنفّذ عملية دمج منزل ذكي تم إنشاؤه سابقًا باستخدام Firebase، ثم ستطبّق إعدادات فحص في Developer Console، وستنشئ تطبيقًا محليًا باستخدام TypeScript لإرسال أوامر مكتوبة بلغة Node.js إلى جهاز غسالة افتراضي.

المُعطيات

  • كيفية تفعيل خدمة "تنفيذ الطلب محليًا" وإعدادها في Developer Console
  • كيفية استخدام حزمة تطوير البرامج (SDK) المحلية للمنزل لكتابة تطبيق تنفيذ محلي
  • كيفية تصحيح أخطاء تطبيق التنفيذ المحلي الذي تم تحميله على مكبّر صوت Google Home أو شاشة Google Nest الذكية

المتطلبات

  • أحدث إصدار من Google Chrome
  • جهاز iOS أو Android مثبّت عليه تطبيق Google Home
  • مكبّر صوت ذكي Google Home أو شاشة ذكية Google Nest
  • الإصدار 10.16 من Node.js أو إصدار أحدث
  • حساب Google
  • حساب فوترة على Google Cloud

2. الخطوات الأولى

تفعيل "عناصر التحكّم في النشاط"

لاستخدام "مساعد Google"، عليك مشاركة بيانات نشاط معيّنة مع Google. يحتاج "مساعد Google" إلى هذه البيانات ليعمل بشكلٍ سليم، ولكنّ شرط مشاركة البيانات ليس خاصًا بحزمة تطوير البرامج (SDK). لمشاركة هذه البيانات، عليك إنشاء حساب على Google إذا لم يكن لديك حساب. يمكنك استخدام أي حساب على Google، وليس بالضرورة أن يكون حساب المطوِّر.

افتح صفحة "عناصر التحكّم في النشاط" لحساب Google الذي تريد استخدامه مع "مساعد Google".

تأكَّد من تفعيل مفاتيح التبديل التالية:

  • النشاط على الويب وفي التطبيقات: بالإضافة إلى ذلك، احرص على وضع علامة في المربّع تضمين سجلّ Chrome والأنشطة من المواقع الإلكترونية والتطبيقات والأجهزة التي تستخدم خدمات Google.
  • معلومات الجهاز
  • التفاعل الصوتي مع الجهاز

إنشاء مشروع دمج من السحابة الإلكترونية إلى السحابة الإلكترونية

  1. انتقِل إلى Play Console.
  2. انقر على إنشاء مشروع، وأدخِل اسمًا للمشروع، ثم انقر على إنشاء مشروع.

تسمية المشروع

اختيار عملية الدمج من السحابة الإلكترونية إلى السحابة الإلكترونية

في الصفحة الرئيسية للمشروع في Developer Console، انقر على إضافة عملية دمج من السحابة الإلكترونية إلى السحابة الإلكترونية ضمن من السحابة الإلكترونية إلى السحابة الإلكترونية.

إضافة عملية دمج من السحابة الإلكترونية إلى السحابة الإلكترونية

تثبيت Firebase CLI

ستتيح لك واجهة سطر الأوامر (CLI) في Firebase عرض تطبيقات الويب محليًا ونشر تطبيق الويب على خدمة استضافة Firebase.

لتثبيت واجهة سطر الأوامر، شغِّل أمر npm التالي من الوحدة الطرفية:

npm install -g firebase-tools

للتحقّق من تثبيت واجهة سطر الأوامر بشكل صحيح، نفِّذ ما يلي:

firebase --version

امنح أداة سطر الأوامر (CLI) في Firebase إذن الوصول إلى حسابك على Google من خلال تنفيذ الأمر التالي:

firebase login

تفعيل HomeGraph API

تتيح HomeGraph API تخزين الأجهزة وحالاتها والاستعلام عنها ضمن قاعدة بيانات Home Graph الخاصة بالمستخدم. لاستخدام واجهة برمجة التطبيقات هذه، عليك أولاً فتح وحدة تحكّم Google Cloud وتفعيل HomeGraph API.

في Google Cloud Console، احرص على اختيار المشروع الذي يتطابق مع <project-id>. لعملية الدمج. بعد ذلك، في شاشة "مكتبة واجهات برمجة التطبيقات" الخاصة بواجهة HomeGraph API، انقر على تفعيل.

5SVCzM8IZLi_9DV8M0nEklv16NXkpvM0bIzQK2hSyKyvnFHBxPOz90rbr72ayxzmxd5aNROOqC_Cp4outbdlwJdObDs0DIE_8vYzw6dovoVrP9IZWlWsZxDS7UHOi1jiRbDMG8MqUA

3- تشغيل التطبيق النموذجي

بعد إعداد بيئة التطوير، يمكنك نشر المشروع التجريبي للتأكّد من ضبط كل شيء بشكلٍ صحيح.

الحصول على رمز المصدر

انقر على الرابط التالي لتنزيل نموذج هذا الدرس العملي على جهاز التطوير:

...أو يمكنك استنساخ مستودع GitHub من سطر الأوامر:

git clone https://github.com/google-home/smarthome-local.git

لمحة عن المشروع

يحتوي المشروع الأوّلي على الدلائل الفرعية التالية:

  • public—واجهة مستخدم الويب الأمامية للتحكّم في الغسالة الذكية ومراقبتها
  • functions—وظائف السحابة الإلكترونية التي تنفّذ ميزة "التنفيذ السحابي" لعملية الدمج من السحابة الإلكترونية إلى السحابة الإلكترونية
  • local—مشروع تطبيق بسيط لتنفيذ الطلبات محليًا مع تضمين نماذج أولية لمعالجات الأهداف index.ts

يتضمّن التنفيذ السحابي المقدَّم الوظائف التالية في index.js:

  • fakeauth—نقطة نهاية التفويض لربط الحسابات
  • faketoken: نقطة نهاية الرمز المميز لربط الحساب
  • smarthome: نقطة نهاية تنفيذ الطلبات المتعلقة بالمنزل الذكي
  • reportstate—يستدعي HomeGraph API عند حدوث تغييرات في حالة الجهاز
  • updateDevice: نقطة النهاية التي يستخدمها الجهاز الافتراضي لتفعيل Report State

الربط مع Firebase

انتقِل إلى الدليل app-start، ثمّ أعدّ واجهة سطر الأوامر (CLI) في Firebase باستخدام مشروع دمج Cloud-to-cloud:

cd app-start
firebase use <project-id>

ضبط مشروع Firebase

إعداد مشروع Firebase

firebase init

اختَر ميزات واجهة سطر الأوامر وRealtime Database وميزة Functions.

? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter
 to confirm your choices. (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to
 proceed)
>( ) Data Connect: Set up a Firebase Data Connect service
 ( ) Firestore: Configure security rules and indexes files for Firestore
 ( ) Genkit: Setup a new Genkit project with Firebase
 (*) Functions: Configure a Cloud Functions directory and its files
 ( ) App Hosting: Configure an apphosting.yaml file for App Hosting
 ( ) Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys
 ( ) Storage: Configure a security rules file for Cloud Storage
 ( ) Emulators: Set up local emulators for Firebase products
 ( ) Remote Config: Configure a template file for Remote Config
 ( ) Extensions: Set up an empty Extensions manifest
 (*) Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision
default instance
 ( ) Data Connect: Set up a Firebase Data Connect service
 ( ) Firestore: Configure security rules and indexes files for Firestore

سيؤدي ذلك إلى تهيئة واجهات برمجة التطبيقات والميزات اللازمة لمشروعك.

عندما يُطلب منك ذلك، ابدأ Realtime Database. يمكنك استخدام الموقع الجغرافي التلقائي لمثيل قاعدة البيانات.

? It seems like you haven't initialized Realtime Database in your project yet. Do you want to set it up?
Yes

? Please choose the location for your default Realtime Database instance:
us-central1

بما أنّك تستخدم رمز المشروع المبدئي، اختَر الملف التلقائي لقواعد الأمان، وتأكَّد من عدم الكتابة فوق ملف قواعد البيانات الحالي.

? File database.rules.json already exists. Do you want to overwrite it with the Realtime Database Security Rules for <project-ID>-default-rtdb from the Firebase Console?
No

إذا كنت تعيد تهيئة مشروعك، اختَر استبدال عندما يُطلب منك تحديد ما إذا كنت تريد تهيئة قاعدة رموز أو استبدالها.

? Would you like to initialize a new codebase, or overwrite an existing one?
Overwrite

عند ضبط إعدادات "الدوال"، عليك استخدام الملفات التلقائية والتأكّد من عدم الكتابة فوق ملفَي index.js وpackage.json الحاليَين في نموذج المشروع.

? What language would you like to use to write Cloud Functions?
JavaScript

? Do you want to use ESLint to catch probable bugs and enforce style?
No

? File functions/package.json already exists. Overwrite?
No

? File functions/index.js already exists. Overwrite?
No

إذا كنت تعيد تهيئة مشروعك، اختَر لا عندما يُطلب منك تحديد ما إذا كنت تريد تهيئة أو الكتابة فوق functions/.gitignore.

? File functions/.gitignore already exists. Overwrite?
No
? Do you want to install dependencies with npm now?
Yes

إذا تم تفعيل ESLint عن طريق الخطأ، تتوفّر طريقتان لإيقافه:

  1. باستخدام واجهة المستخدم الرسومية، انتقِل إلى المجلد ../functions ضمن المشروع، واختَر الملف المخفي .eslintrc.js واحذفه. لا تخلط بينه وبين .eslintrc.json الذي يحمل اسمًا مشابهًا.
  2. باستخدام سطر الأوامر:
    cd functions
    rm .eslintrc.js
    

لضمان توفّر إعدادات Firebase صحيحة وكاملة، انسخ الملف firebase.json من الدليل washer-done إلى الدليل washer-start، مع استبدال الملف الموجود في washer-start.

في دليل washer-start:

cp -vp ../washer-done/firebase.json .

النشر على Firebase

بعد تثبيت التبعيات وإعداد مشروعك، أنت الآن جاهز لتشغيل التطبيق للمرة الأولى.

firebase deploy

في ما يلي نتائج وحدة التحكّم التي من المفترض أن تظهر لك:

...

✔ Deploy complete!

Project Console: https://console.firebase.google.com/project/<project-id>/overview
Hosting URL: https://<project-id>.web.app

ينشر هذا الأمر تطبيقًا على الويب، بالإضافة إلى العديد من وظائف Firebase السحابية.

افتح عنوان URL للاستضافة في المتصفّح (https://<project-id>.web.app) لعرض تطبيق الويب. ستظهر لك الواجهة التالية:

L60eA7MOnPmbBMl2XMipT9MdnP-RaVjyjf0Y93Y1b7mEyIsqZrrwczE7D3RQISRs-iusL1g4XbNmGhuA6-5sLcWefnczwNJEPfNLtwBsO4Tb9YvcAZBI6_rX19z8rxbik9Vq8F2fwg

تمثّل واجهة مستخدم الويب هذه منصة تابعة لجهة خارجية لعرض حالات الأجهزة أو تعديلها. لبدء ملء قاعدة البيانات بمعلومات الجهاز، انقر على تعديل. لن تظهر أي تغييرات على الصفحة، ولكن سيتم تخزين الحالة الحالية للغسالة في قاعدة البيانات.

حان الوقت الآن لربط الخدمة السحابية التي نشرتها بخدمة "مساعد Google" باستخدام Developer Console.

ضبط مشروعك في Developer Console

في علامة التبويب تطوير، أضِف اسمًا معروضًا للتفاعل. سيظهر هذا الاسم في تطبيق Google Home.

إضافة اسم معروض

ضِمن العلامة التجارية للتطبيق، حمِّل ملف png لرمز التطبيق بحجم 144 × 144 بكسل، وأطلِق عليه الاسم .png.

إضافة رمز تطبيق

لتفعيل ربط الحساب، استخدِم إعدادات ربط الحساب التالية:

معرِّف العميل

ABC123

سر العميل

DEF456

عنوان URL للترخيص

https://us-central1-<project-id>.cloudfunctions.net/fakeauth

عنوان URL للرمز المميز

https://us-central1-<project-id>.cloudfunctions.net/faketoken

تعديل عناوين URL لربط الحسابات

ضمن عنوان URL لتنفيذ الطلبات على السحابة الإلكترونية، أدخِل عنوان URL لوظيفة السحابة الإلكترونية التي توفّر تنفيذ الطلبات المتعلقة بأجهزة المنزل الذكي.

https://us-central1-<project-id>.cloudfunctions.net/smarthome

إضافة عنوان URL للدالة السحابية

انقر على حفظ لحفظ إعدادات مشروعك، ثمّ انقر على التالي: اختبار لتفعيل الاختبار في مشروعك.

اختبار عملية الدمج من السحابة الإلكترونية إلى السحابة الإلكترونية

يمكنك الآن البدء في تنفيذ خطافات الويب اللازمة لربط حالة الجهاز بالمساعد.

لاختبار عملية الربط بين الخدمات السحابية، عليك ربط مشروعك بحساب Google. يتيح ذلك إجراء الاختبار من خلال مساحات عرض "مساعد Google" وتطبيق Google Home اللذين تم تسجيل الدخول إليهما باستخدام الحساب نفسه.

  1. على هاتفك، افتح إعدادات "مساعد Google". يُرجى العلم أنّه يجب تسجيل الدخول باستخدام الحساب نفسه المستخدَم في وحدة التحكّم.
  2. انتقِل إلى مساعد Google > الإعدادات > التحكم في المنزل (ضمن "مساعد Google").
  3. انقر على رمز البحث في أعلى يسار الصفحة.
  4. ابحث عن تطبيق الاختبار باستخدام البادئة [test] للعثور على تطبيق الاختبار المحدّد.
  5. اختَر هذا العنصر. بعد ذلك، سيصادق "مساعد Google" على خدمتك ويرسل طلبًا إلى SYNC، ويطلب من خدمتك تقديم قائمة بالأجهزة للمستخدم.

افتح تطبيق Google Home وتأكَّد من إمكانية رؤية جهاز الغسالة.

XcWmBVamBZtPfOFqtsr5I38stPWTqDcMfQwbBjetBgxt0FCjEs285pa9K3QXSASptw0KYN2G8yfkT0-xg664V4PjqMreDDs-HPegHjOc4EVtReYPu-WKZyygq9Xmkf8X8z9177nBjQ

تأكَّد من إمكانية التحكّم في الغسّالة باستخدام الطلبات الصوتية في تطبيق Google Home. من المفترض أيضًا أن ترى تغييرًا في حالة الجهاز في واجهة مستخدم الويب الأمامية لخدمة التنفيذ السحابي.

يمكنك الآن البدء بإضافة ميزة "التنفيذ المحلي" إلى عملية الدمج.

4. تعديل ميزة "التنفيذ على السحابة الإلكترونية"

لإتاحة خدمة التنفيذ المحلي، عليك إضافة حقل جديد لكل جهاز باسم otherDeviceIds إلى استجابة SYNC على السحابة الإلكترونية يتضمّن معرّفًا محليًا فريدًا للجهاز. يشير هذا الحقل أيضًا إلى إمكانية التحكّم في هذا الجهاز محليًا.

أضِف الحقل otherDeviceIds إلى الردّ SYNC كما هو موضّح في مقتطف الرمز التالي:

functions/index.js

app.onSync((body) => {
  return {
    requestId: body.requestId,
    payload: {
      agentUserId: '123',
      devices: [{
        id: 'washer',
        type: 'action.devices.types.WASHER',
        traits: [ ... ],
        name: { ... },
        deviceInfo: { ... },
        willReportState: true,
        attributes: {
          pausable: true,
        },
        otherDeviceIds: [{
          deviceId: 'deviceid123',
        }],
      }],
    },
  };
});

انشر المشروع المعدَّل على Firebase:

firebase deploy --only functions

بعد اكتمال عملية النشر، انتقِل إلى واجهة مستخدم الويب وانقر على الزر إعادة التحميلae8d3b25777a5e30.png في شريط الأدوات. يؤدي ذلك إلى بدء عملية "طلب المزامنة" لكي يتلقّى "مساعد Google" بيانات الردّ المعدَّلة من SYNC.

bf4f6a866160a982.png

5- ضبط إعدادات التنفيذ المحلي

في هذا القسم، ستضيف خيارات الإعداد اللازمة لتنفيذ الطلبات محليًا إلى عملية الدمج من السحابة الإلكترونية إلى السحابة الإلكترونية. أثناء عملية التطوير، ستنشر تطبيق Local Fulfillment على "استضافة Firebase"، حيث يمكن لجهاز Google Home الوصول إليه وتنزيله.

في Google Home Developer Console، انتقِل إلى المشروع > الربط بين السحابتين على يمين الشاشة، ثم انقر على تعديل لعملية الربط. في صفحة الإعداد والضبط، انتقِل إلى التنفيذ المحلي وفعِّل الإعداد. أدخِل عنوان URL التالي في كل حقل من حقول عناوين URL التجريبية، وأدرِج رقم تعريف مشروعك، ثم انقر على حفظ:

https://<project-id>.web.app/local-home/index.html

local-fulfillment.png

بعد ذلك، علينا تحديد الطريقة التي يجب أن تتعرّف بها أجهزة Google Home على الأجهزة الذكية المحلية. تتوافق منصة Local Home مع العديد من البروتوكولات لاكتشاف الأجهزة، بما في ذلك mDNS وUPnP وUDP broadcast. ستستخدم بث UDP للعثور على الغسالة الذكية.

انقر على + إضافة إعدادات فحص ضمن اكتشاف الأجهزة لإضافة إعدادات فحص جديدة. اختَر UDP كبروتوكول، واملأ السمات التالية:

الحقل

الوصف

القيمة المقترَحة

عنوان الاستلام

عنوان اكتشاف UDP

255.255.255.255

منفذ البث

المنفذ الذي يرسل منه Google Home بث UDP

3311

منفذ الاستماع

المنفذ الذي يستمع من خلاله Google Home إلى الرد

3312

حزمة الاستكشاف

حمولة بيانات بث UDP

48656c6c6f4c6f63616c486f6d6553444b

device-discovery.png

أخيرًا، انقر على حفظ في أسفل النافذة لنشر التغييرات.

6. تنفيذ خدمة تلبية الطلبات محليًا

ستطوّر تطبيقك الذي يتيح تنفيذ الطلبات محليًا باستخدام TypeScript من خلال حزمة تعريفات Local Home SDK. ألقِ نظرة على الهيكل العظمي المقدَّم في المشروع الأوّلي:

local/index.ts

/// <reference types="@google/local-home-sdk" />

import App = smarthome.App;
import Constants = smarthome.Constants;
import DataFlow = smarthome.DataFlow;
import Execute = smarthome.Execute;
import Intents = smarthome.Intents;
import IntentFlow = smarthome.IntentFlow;

...

class LocalExecutionApp {

  constructor(private readonly app: App) { }

  identifyHandler(request: IntentFlow.IdentifyRequest):
      Promise<IntentFlow.IdentifyResponse> {
    // TODO: Implement device identification
  }

  executeHandler(request: IntentFlow.ExecuteRequest):
      Promise<IntentFlow.ExecuteResponse> {
    // TODO: Implement local fulfillment
  }

  ...
}

const localHomeSdk = new App('1.0.0');
const localApp = new LocalExecutionApp(localHomeSdk);
localHomeSdk
  .onIdentify(localApp.identifyHandler.bind(localApp))
  .onExecute(localApp.executeHandler.bind(localApp))
  .listen()
  .then(() => console.log('Ready'))
  .catch((e: Error) => console.error(e));

المكوّن الأساسي لعملية التنفيذ المحلية هو الفئة smarthome.App. يربط مشروع البداية معالِجات للغرضين IDENTIFY وEXECUTE، ثم يستدعي الطريقة listen() لإعلام حزمة Local Home SDK بأنّ التطبيق جاهز.

إضافة معالج IDENTIFY

يُفعّل Local Home SDK معالج IDENTIFY عندما يرصد جهاز Google Home أجهزة لم يتم التحقّق منها على الشبكة المحلية استنادًا إلى إعدادات الفحص المتوفّرة في Developer Console.

في الوقت نفسه، تستدعي المنصة identifyHandler مع بيانات الفحص الناتجة عندما يعثر Google على جهاز مطابق. في تطبيقك، يتم إجراء عملية المسح الضوئي باستخدام بث UDP، وتتضمّن بيانات المسح الضوئي المقدَّمة إلى معالج IDENTIFY حمولة الرد التي يرسلها الجهاز المحلي.

تعرض الدالة المعالِجة مثيلاً من IdentifyResponse يحتوي على معرّف فريد للجهاز المحلي. أضِف الرمز التالي إلى طريقة identifyHandler لمعالجة استجابة UDP الواردة من الجهاز المحلي وتحديد رقم تعريف الجهاز المحلي المناسب:

local/index .ts

identifyHandler(request: IntentFlow.IdentifyRequest):
    Promise<IntentFlow.IdentifyResponse> {
  console.log("IDENTIFY intent: " + JSON.stringify(request, null, 2));

  const scanData = request.inputs[0].payload.device.udpScanData;
  if (!scanData) {
    const err = new IntentFlow.HandlerError(request.requestId,
        'invalid_request', 'Invalid scan data');
    return Promise.reject(err);
  }

  // In this codelab, the scan data contains only local device ID.
  const localDeviceId = Buffer.from(scanData.data, 'hex');

  const response: IntentFlow.IdentifyResponse = {
    intent: Intents.IDENTIFY,
    requestId: request.requestId,
    payload: {
      device: {
        id: 'washer',
        verificationId: localDeviceId.toString(),
      }
    }
  };
  console.log("IDENTIFY response: " + JSON.stringify(response, null, 2));

  return Promise.resolve(response);
}

يُرجى العِلم أنّ الحقل verificationId يجب أن يتطابق مع إحدى قيم otherDeviceIds في استجابة SYNC، ما يشير إلى أنّ الجهاز متاح للتنفيذ المحلي في مخطط المنزل الخاص بالمستخدم. بعد أن تعثر Google على تطابق، يُعتبر الجهاز مثبَتًا وجاهزًا لتنفيذ الطلبات محليًا.

إضافة معالج EXECUTE

تفعّل حزمة تطوير البرامج (SDK) المحلية للمنزل معالج EXECUTE عندما يتلقّى جهاز يتيح التنفيذ المحلي أمرًا. محتوى النية المحلية يعادل نية EXECUTE المُرسَلة إلى خدمة تنفيذ الطلبات في السحابة الإلكترونية، لذا فإنّ منطق معالجة النية محليًا يشبه طريقة التعامل معها في السحابة الإلكترونية.

يمكن للتطبيق استخدام مآخذ توصيل TCP/UDP أو طلبات HTTP(S) للتواصل مع الأجهزة المحلية. في هذا الدرس العملي، يتم استخدام HTTP كبروتوكول للتحكّم في الجهاز الافتراضي. يتم تحديد رقم المنفذ في index.ts كمتغير SERVER_PORT.

أضِف الرمز التالي إلى طريقة executeHandler لمعالجة الأوامر الواردة وإرسالها إلى الجهاز المحلي عبر HTTP:

local/index.ts

executeHandler(request: IntentFlow.ExecuteRequest):
    Promise<IntentFlow.ExecuteResponse> {
  console.log("EXECUTE intent: " + JSON.stringify(request, null, 2));

  const command = request.inputs[0].payload.commands[0];
  const execution = command.execution[0];
  const response = new Execute.Response.Builder()
    .setRequestId(request.requestId);

  const promises: Array<Promise<void>> = command.devices.map((device) => {
    console.log("Handling EXECUTE intent for device: " + JSON.stringify(device));

    // Convert execution params to a string for the local device
    const params = execution.params as IWasherParams;
    const payload = this.getDataForCommand(execution.command, params);

    // Create a command to send over the local network
    const radioCommand = new DataFlow.HttpRequestData();
    radioCommand.requestId = request.requestId;
    radioCommand.deviceId = device.id;
    radioCommand.data = JSON.stringify(payload);
    radioCommand.dataType = 'application/json';
    radioCommand.port = SERVER_PORT;
    radioCommand.method = Constants.HttpOperation.POST;
    radioCommand.isSecure = false;

    console.log("Sending request to the smart home device:", payload);

    return this.app.getDeviceManager()
      .send(radioCommand)
      .then(() => {
        const state = {online: true};
        response.setSuccessState(device.id, Object.assign(state, params));
        console.log(`Command successfully sent to ${device.id}`);
      })
      .catch((e: IntentFlow.HandlerError) => {
        e.errorCode = e.errorCode || 'invalid_request';
        response.setErrorState(device.id, e.errorCode);
        console.error('An error occurred sending the command', e.errorCode);
      });
  });

  return Promise.all(promises)
    .then(() => {
      return response.build();
    })
    .catch((e) => {
      const err = new IntentFlow.HandlerError(request.requestId,
          'invalid_request', e.message);
      return Promise.reject(err);
    });
}

تجميع تطبيق TypeScript

انتقِل إلى دليل local/ ونفِّذ الأوامر التالية لتنزيل برنامج ترجمة TypeScript وتجميع التطبيق:

cd local
npm install
npm run build

يؤدي ذلك إلى تجميع مصدر index.ts (TypeScript) ووضع المحتوى التالي في الدليل public/local-home/:

  • bundle.js: ناتج JavaScript المجمَّع الذي يحتوي على التطبيق المحلي والتبعيات
  • index.html—صفحة الاستضافة المحلية المستخدَمة لعرض التطبيق بغرض إجراء الاختبار على الجهاز

نشر مشروع الاختبار

انشر ملفات المشروع المعدَّلة على Firebase Hosting لتتمكّن من الوصول إليها من جهاز Google Home.

firebase deploy --only hosting

7. بدء تشغيل الغسالة الذكية

حان الوقت الآن لاختبار التواصل بين تطبيقك المحلي الخاص بتنفيذ الطلبات والغسالة الذكية. يتضمّن مشروع البداية في الدرس العملي جهاز غسيل ذكي افتراضي مكتوبًا بلغة Node.js، وهو يحاكي جهاز غسيل ذكي يمكن للمستخدمين التحكّم فيه محليًا.

ضبط إعدادات الجهاز

عليك ضبط الجهاز الافتراضي لاستخدام مَعلمات UDP نفسها التي طبّقتها على إعدادات الفحص لاكتشاف الأجهزة في Developer Console. بالإضافة إلى ذلك، عليك إخبار الجهاز الافتراضي برقم تعريف الجهاز المحلي الذي سيتم إرساله ورقم تعريف مشروع Cloud-to-cloud integration الذي سيتم استخدامه لأحداث Report State عند تغيُّر حالة الجهاز.

المعلَمة

القيمة المقترَحة

deviceId

deviceid123

discoveryPortOut

3311

discoveryPacket

HelloLocalHomeSDK

projectId

رقم تعريف مشروع عملية الدمج من السحابة الإلكترونية إلى السحابة الإلكترونية

تشغيل الجهاز

انتقِل إلى الدليل virtual-device/ وشغِّل نص الجهاز البرمجي، مع تمرير مَعلمات الإعدادات كوَسائط:

cd virtual-device
npm install
npm start -- \
  --deviceId=deviceid123 --projectId=<project-id> \
  --discoveryPortOut=3311 --discoveryPacket=HelloLocalHomeSDK

تأكَّد من أنّ نص الجهاز البرمجي يتم تنفيذه باستخدام المَعلمات المتوقّعة:

(...): UDP Server listening on 3311
(...): Device listening on port 3388
(...): Report State successful

8. تصحيح أخطاء تطبيق TypeScript

في القسم التالي، ستتحقّق من أنّ جهاز Google Home يمكنه إجراء المسح الضوئي والتعرّف على الغسالة الذكية الافتراضية وإرسال الأوامر إليها بشكل صحيح عبر الشبكة المحلية. يمكنك استخدام أدوات المطوّرين في Google Chrome للاتصال بجهاز Google Home وعرض سجلّات وحدة التحكّم وتصحيح أخطاء تطبيق TypeScript.

ربط "أدوات مطوّري برامج Chrome"

لربط أداة تصحيح الأخطاء بتطبيق التنفيذ المحلي، اتّبِع الخطوات التالية:

  1. تأكَّد من ربط جهاز Google Home بمستخدم لديه إذن الوصول إلى مشروع Developer Console.
  2. أعِد تشغيل جهاز Google Home، ما يتيح له الحصول على عنوان URL الخاص بملف HTML بالإضافة إلى إعدادات الفحص التي وضعتها في Developer Console.
  3. شغِّل Chrome على جهاز التطوير.
  4. افتح علامة تبويب جديدة في Chrome وأدخِل chrome://inspect في حقل العنوان لتشغيل "أداة الفحص".

من المفترض أن تظهر لك قائمة بالأجهزة على الصفحة، ويجب أن يظهر عنوان URL لتطبيقك تحت اسم جهاز Google Home.

567f97789a7d8846.png

تشغيل أداة الفحص

انقر على فحص ضمن عنوان URL لتطبيقك لبدء تشغيل "أدوات مطوّري برامج Chrome". اختَر علامة التبويب وحدة التحكّم وتأكَّد من إمكانية الاطّلاع على محتوى الغرض IDENTIFY الذي يطبعه تطبيق TypeScript.

6b67ded470a4c8be.png

يعني هذا الناتج أنّ تطبيق التنفيذ المحلي اكتشف الجهاز الافتراضي وحدّده بنجاح.

اختبار تلبية الطلبات على المستوى المحلي

إرسال أوامر إلى جهازك باستخدام عناصر التحكّم باللمس في تطبيق Google Home أو من خلال الطلبات الصوتية إلى جهاز Google Home، مثل:

"Ok Google، شغِّل الغسالة".

Ok Google، شغِّل الغسالة".

"Ok Google، أوقِف الغسالة".

من المفترض أن يؤدي ذلك إلى إرسال المنصة EXECUTE إلى تطبيق TypeScript.

bc030517dacc3ac9.png

تأكَّد من إمكانية الاطّلاع على تغيير حالة الغسالة الذكية المحلية مع كل أمر.

...
***** The washer is RUNNING *****
...
***** The washer is STOPPED *****

9- تهانينا

764dbc83b95782a.png

تهانينا! استخدمت Local Home SDK لدمج ميزة "التنفيذ المحلي" في عملية دمج من السحابة إلى السحابة.

مزيد من المعلومات

في ما يلي بعض الإجراءات الإضافية التي يمكنك تجربتها:

  • غيِّر إعدادات البحث واجعله يعمل. على سبيل المثال، جرِّب استخدام منفذ UDP أو حزمة اكتشاف مختلفة.
  • عدِّل قاعدة رموز الجهاز الذكي الافتراضي لتشغيلها على جهاز مدمج، مثل Raspberry Pi، واستخدِم مؤشرات LED أو شاشة لعرض الحالة الحالية.