ولدعم تلبية الطلبات على المستوى المحلي، عليك إنشاء تطبيق للتعامل مع هذه العوامل. أهداف المنزل المزوّد بأجهزة ذكية:
IDENTIFY
: يتيح استكشاف الأجهزة الذكية التي يمكن التحكّم فيها محليًا. تشير رسالة الأشكال البيانية يستخرج معالج intent البيانات التي يعرضها جهازك الذكي أثناء الاكتشاف وترسلها في رد إلى Google.EXECUTE
: يتيح تنفيذ الأوامر.QUERY
: يتيح الاستعلام عن حالة الجهاز.REACHABLE_DEVICES
: (اختياري) يتيح استكشاف التطبيقات التي يمكن التحكّم فيها محليًا الأجهزة الطرفية خلف جهاز موزع (أو جسر).
يعمل هذا التطبيق على أجهزة Google Home أو Google Nest الخاصة بالمستخدم ويربط جهازك الذكي بـ مساعد Google ويمكنك إنشاء التطبيق باستخدام TypeScript (مفضّل) أو JavaScript.
ننصحك باستخدام أداة TypeScript لأنه يمكنك الاستفادة من عمليات الربط لضمان تطابق البيانات التي يعرضها تطبيقك مع الأنواع التي تتوقعه المنصة.
لمزيد من التفاصيل حول واجهة برمجة التطبيقات، يمكنك الاطّلاع على مرجع واجهة برمجة التطبيقات لحزمة تطوير البرامج (SDK) لمنزل Local Home
توضِّح المقتطفات التالية كيفية إعداد تطبيق توصيل الطلبات على الجهاز نرفق المعالجات.
import App = smarthome.App; const localHomeApp: App = new App("1.0.0"); localHomeApp .onIdentify(identifyHandler) .onExecute(executeHandler) .listen() .then(() => { console.log("Ready"); });
import App = smarthome.App; const localHomeApp: App = new App("1.0.0"); localHomeApp .onIdentify(identifyHandler) .onReachableDevices(reachableDevicesHandler) .onExecute(executeHandler) .listen() .then(() => { console.log("Ready"); });
إنشاء مشروعك
لنشر تطبيق محلي لتوصيل الطلبات، يجب إنشاء حزمة JavaScript. للتعليمة البرمجية وجميع تبعياتها.
استخدام مشروع تطبيق توصيل الطلبات على المستوى المحلي أداة الإعداد لتمهيد بنية المشروع المناسبة باستخدام أداة الحزم المفضلة لديك التكوين.
قوالب المشاريع
لاختيار إعدادات أداة التجميع، شغِّل الأمر npm init
كما هو موضَّح في
في ما يلي الأمثلة:
TypeScript بدون إعدادات أداة التجميع:
npm init @google/local-home-app project-directory/ --bundler none
هيكل المشروع:
project-directory/ ├── node_modules/ ├── package.json ├── .gitignore ├── index.ts ├── test.ts ├── tsconfig.json ├── tslint.json └── serve.js
استبدِل project-directory بدليل جديد يحتوي على تطبيق التنفيذ المحلي.
TypeScript مع أداة تجميع webpack التكوين:
npm init @google/local-home-app project-directory/ --bundler webpack
هيكل المشروع:
project-directory/ ├── node_modules/ ├── package.json ├── .gitignore ├── index.ts ├── test.ts ├── tsconfig.json ├── tslint.json ├── webpack.config.web.js ├── webpack.config.node.js └── serve.js
استبدِل project-directory بدليل جديد يحتوي على تطبيق التنفيذ المحلي.
TypeScript مع ميزة Rollup إعدادات أداة التجميع:
npm init @google/local-home-app project-directory/ --bundler rollup
هيكل المشروع:
project-directory/ ├── node_modules/ ├── package.json ├── .gitignore ├── index.ts ├── test.ts ├── tsconfig.json ├── tslint.json ├── rollup.config.js └── serve.js
استبدِل project-directory بدليل جديد يحتوي على تطبيق التنفيذ المحلي.
TypeScript مع Parcel إعدادات أداة التجميع:
npm init @google/local-home-app project-directory/ --bundler parcel
هيكل المشروع:
project-directory/ ├── node_modules/ ├── package.json ├── .gitignore ├── index.ts ├── test.ts ├── tsconfig.json ├── tslint.json └── serve.js
استبدِل project-directory بدليل جديد يحتوي على تطبيق التنفيذ المحلي.
تنفيذ المهام الشائعة على مستوى المشروع
يدعم المشروع الذي تم إنشاؤه npm التالي: النصوص البرمجية:
cd project-directory/ npm run build
يجمّع هذا النص البرمجي مصدر TypeScript ويجمع تطبيقك مع ملحقاته لبيئة وقت تشغيل Chrome في الدليل الفرعي dist/web
وبيئة وقت تشغيل Node.js في الدليل الفرعي dist/node
.
cd project-directory/ npm run lint npm run compile npm test
يتحقّق هذا النص البرمجي من بنية رمز TypeScript، ويجمعه بدون إنتاج أي مخرجات في الدليل الفرعي dist/
، كما ينفِّذ اختبارات مبرمَجة من test.ts
.
cd project-directory/ npm run start
أثناء التطوير، يعرض هذا النص البرمجي حِزم تطبيقك لبيئات وقت تشغيل Chrome وNode.js على الجهاز.
تنفيذ معالج IDENTIFY
سيتم تشغيل معالِج IDENTIFY
عند إعادة تشغيل جهاز Google Home أو Google Nest و
رؤية أجهزة محلية لم يتم التحقق منها (بما في ذلك الأجهزة النهائية المتصلة بمركز التحكم). تشير رسالة الأشكال البيانية
ستبحث منصة الشاشة الرئيسية المحلية عن الأجهزة المحلية باستخدام معلومات إعدادات البحث.
التي حددتها سابقًا وتطلب من معالج IDENTIFY
تقديم نتائج الفحص.
تشير رسالة الأشكال البيانية
IdentifyRequest
من منصة الصفحة الرئيسية المحلية على بيانات الفحص
LocalIdentifiedDevice
مثال. تتم تعبئة مثيل device
واحد فقط، بناءً على إعدادات الفحص.
الذي اكتشف الجهاز.
وإذا تطابقت نتائج الفحص مع جهازك، من المفترض أن يعرض معالج IDENTIFY
IdentifyResponsePayload
يتضمن كائن device
مع
البيانات الوصفية للمنزل المزوّد بأجهزة ذكية (مثل الأنواع والسمات وحالة التقرير)
وتنشئ Google عملية ربط بالجهاز إذا
تتطابق verificationId
من استجابة IDENTIFY
مع أحد
قيم otherDeviceIds
التي عرضتها استجابة SYNC
مثال
توضِّح المقتطفات التالية كيفية إنشاء معالجات IDENTIFY
عمليات دمج الأجهزة والمركز المستقلّة على التوالي.
const identifyHandler = (request: IntentFlow.IdentifyRequest): IntentFlow.IdentifyResponse => { // Obtain scan data from protocol defined in your scan config const device = request.inputs[0].payload.device; if (device.udpScanData === undefined) { throw Error("Missing discovery response"); } const scanData = device.udpScanData.data; // Decode scan data to obtain metadata about local device const verificationId = "local-device-id"; // Return a response const response: IntentFlow.IdentifyResponse = { intent: Intents.IDENTIFY, requestId: request.requestId, payload: { device: { id: device.id || "", verificationId, // Must match otherDeviceIds in SYNC response }, }, }; return response; };
const identifyHandler = (request: IntentFlow.IdentifyRequest): IntentFlow.IdentifyResponse => { // Obtain scan data from protocol defined in your scan config const device = request.inputs[0].payload.device; if (device.udpScanData === undefined) { throw Error("Missing discovery response"); } const scanData = device.udpScanData.data; // Decode scan data to obtain metadata about local device const proxyDeviceId = "local-hub-id"; // Return a response const response: IntentFlow.IdentifyResponse = { intent: Intents.IDENTIFY, requestId: request.requestId, payload: { device: { id: proxyDeviceId, isProxy: true, // Device can control other local devices isLocalOnly: true, // Device not present in `SYNC` response }, }, }; return response; };
تحديد الأجهزة وراء الموزع (hub)
إذا تعرّفت Google على جهاز موزع، سيتعامل مع الموزع على أنه القناة بالأجهزة النهائية المتصلة بالموزع (hub) ومحاولة التحقق من هذه الأجهزة النهائية.
لتمكين Google من التأكُّد من توفُّر جهاز موزع، اتّبِع الخطوات التالية
تعليمات لمعالِج IDENTIFY
:
- إذا أشار ردّ
SYNC
إلى أرقام تعريف الأجهزة النهائية المتصلة بـ الموزع، تم ضبطisProxy
علىtrue
فيIdentifyResponsePayload
- إذا لم تبلغ استجابة
SYNC
عن جهاز الموزع، اضبطisLocalOnly
في شكلtrue
فيIdentifyResponsePayload
- يحتوي الحقل
device.id
على رقم تعريف الجهاز المحلي لجهاز الموزع نفسه.
تنفيذ المعالِج REACHABLE_جرب (عمليات دمج المركز فقط)
ترسل Google الغرض REACHABLE_DEVICES
من أجل تأكيد الأجهزة النهائية.
يمكن التحكم فيه محليًا. يتم تفعيل هذا الغرض في كل مرة تُجري فيها Google
فحص استكشافي (مرة واحدة كل دقيقة تقريبًا)، طالما تم اكتشاف أن الموزع (hub)
أن تكون متصلاً بالإنترنت.
لقد نفّذت معالج REACHABLE_DEVICES
بشكل مشابه لمعالج IDENTIFY
.
المعالِج، باستثناء أنّ المعالج يحتاج إلى جمع أرقام تعريف إضافية للأجهزة
يمكن الوصول إليها بواسطة جهاز الخادم الوكيل المحلي (أي الموزع). تشير رسالة الأشكال البيانية
يحتوي الحقل device.verificationId
على رقم تعريف الجهاز المحلي لجهاز نهائي.
المتصلة بالموزع (hub)
تشير رسالة الأشكال البيانية
ReachableDevicesRequest
من منصة الصفحة الرئيسية المحلية يحتوي على مثيل
LocalIdentifiedDevice
من خلال هذا المثيل، يمكنك الحصول على معرّف الجهاز الوكيل بالإضافة إلى بيانات من
نتائج الفحص.
يجب أن يعرض معالج REACHABLE_DEVICES
ReachableDevicesPayload
كائن يتضمن كائن devices
يحتوي على صفيف
verificationId
تمثل القيم الأجهزة النهائية التي يتحكم فيها الموزع (hub). تشير رسالة الأشكال البيانية
يجب أن تتطابق قيم verificationId
مع إحدى otherDeviceIds
من
ردّ SYNC
يعرض المقتطف التالي كيفية إنشاء REACHABLE_DEVICES
.
.
const reachableDevicesHandler = (request: IntentFlow.ReachableDevicesRequest): IntentFlow.ReachableDevicesResponse => { // Reference to the local proxy device const proxyDeviceId = request.inputs[0].payload.device.id; // Gather additional device ids reachable by local proxy device // ... const reachableDevices = [ // Each verificationId must match one of the otherDeviceIds // in the SYNC response { verificationId: "local-device-id-1" }, { verificationId: "local-device-id-2" }, ]; // Return a response const response: IntentFlow.ReachableDevicesResponse = { intent: Intents.REACHABLE_DEVICES, requestId: request.requestId, payload: { devices: reachableDevices, }, }; return response; };
تنفيذ معالج التنفيذ
يعالج معالج EXECUTE
في التطبيق أوامر المستخدم ويستخدم
حزمة تطوير البرامج (SDK) للمنزل المحلي للوصول إلى الأجهزة الذكية من خلال بروتوكول حالي
تمرِّر منصة الصفحة الرئيسية المحلية حمولة البيانات نفسها إلى معالج EXECUTE
بالنسبة إلى EXECUTE
رغبتهم في تنفيذ الخدمات السحابية. وبالمثل، يعرض معالج EXECUTE
.
البيانات الناتجة بالتنسيق نفسه المستخدَم في معالجة هدف EXECUTE
.
لتبسيط إنشاء الرد، يمكنك استخدام
Execute.Response.Builder
الفئة التي توفّرها حزمة تطوير البرامج للمنزل المحلي.
لا يمكن لتطبيقك الوصول مباشرةً إلى عنوان IP للجهاز. بدلاً من ذلك،
استخدام
CommandRequest
لإنشاء أوامر تستند إلى أحد هذه البروتوكولات: UDP أو TCP أو HTTP. ثم قم باستدعاء دالة الرسم
deviceManager.send()
لإرسال الأوامر.
عند استهداف أوامر للأجهزة، استخدم رقم تعريف الجهاز (والمعلمات من
الحقل customData
، إذا كان مضمّنًا) من ردّ SYNC
للتواصل.
بالجهاز.
مثال
يعرض مقتطف الرمز التالي كيفية إنشاء معالج EXECUTE
.
const executeHandler = (request: IntentFlow.ExecuteRequest): Promise<IntentFlow.ExecuteResponse> => { // Extract command(s) and device target(s) from request const command = request.inputs[0].payload.commands[0]; const execution = command.execution[0]; const response = new Execute.Response.Builder() .setRequestId(request.requestId); const result = command.devices.map((device) => { // Target id of the device provided in the SYNC response const deviceId = device.id; // Metadata for the device provided in the SYNC response // Use customData to provide additional required execution parameters const customData: any = device.customData; // Convert execution command into payload for local device let devicePayload: string; // ... // Construct a local device command over TCP const deviceCommand = new DataFlow.TcpRequestData(); deviceCommand.requestId = request.requestId; deviceCommand.deviceId = deviceId; deviceCommand.data = devicePayload; deviceCommand.port = customData.port; deviceCommand.operation = Constants.TcpOperation.WRITE; // Send command to the local device return localHomeApp.getDeviceManager() .send(deviceCommand) .then((result) => { response.setSuccessState(result.deviceId, state); }) .catch((err: IntentFlow.HandlerError) => { err.errorCode = err.errorCode || IntentFlow.ErrorCode.INVALID_REQUEST; response.setErrorState(device.id, err.errorCode); }); }); // Respond once all commands complete return Promise.all(result) .then(() => response.build()); };
تنفيذ معالج QUERY
يعالج معالج QUERY
في التطبيق طلبات المستخدمين ويستخدم
حزمة تطوير البرامج (SDK) للمنزل المحلي للإبلاغ عن حالة أجهزتك الذكية.
تمرر منصة الصفحة الرئيسية المحلية حمولة الطلب نفسها إلى "QUERY" المعالج
التي تعمل بالنسبة إلى QUERY
رغبتهم في تنفيذ الخدمات السحابية. وبالمثل، يعرض معالج QUERY
البيانات.
بالتنسيق نفسه الناتج عن معالجة هدف QUERY
.
إرسال الأوامر إلى الأجهزة الموجودة خلف الموزع (hub)
للتحكّم في الأجهزة النهائية الموجودة خلف وحدة الموزع (hub)، قد تحتاج إلى تقديم معلومات إضافية
في حمولة الأوامر الخاصة بالبروتوكول والتي يتم إرسالها إلى الموزع (hub)
لتحديد الجهاز الذي يعمل عليه الأمر. في بعض الحالات، قد يكون هذا
يمكن الاستنتاج منها مباشرةً من قيمة device.id
، ولكن إذا لم يكن الأمر كذلك،
يجب تضمين هذه البيانات الإضافية كجزء من الحقل customData
.
إذا كنت قد أنشأت تطبيقك باستخدام TypeScript، فتذكر تجميع التطبيق من أجل JavaScript. يمكنك استخدام نظام الوحدات الذي تختاره لكتابة التعليمة البرمجية. تأكَّد من أنّ متصفّح Chrome يتوافق مع هدفك.