برای پشتیبانی از تحقق محلی، باید برنامه ای بسازید تا این اهداف خانه هوشمند را مدیریت کند:
-
IDENTIFY
: از کشف دستگاه های هوشمند قابل کنترل محلی پشتیبانی می کند. Intent handler دادههایی را که دستگاه هوشمند شما در حین کشف برمیگرداند استخراج میکند و در پاسخ به Google ارسال میکند. -
EXECUTE
: از اجرای دستورات پشتیبانی می کند. -
QUERY
: از وضعیت دستگاه پرس و جو پشتیبانی می کند. -
REACHABLE_DEVICES
: (اختیاری) از کشف دستگاههای انتهایی قابل کنترل محلی در پشت دستگاه هاب (یا پل) پشتیبانی میکند.
این برنامه روی دستگاههای Google Home یا Google Nest کاربر اجرا میشود و دستگاه هوشمند شما را به Assistant متصل میکند. می توانید برنامه را با استفاده از TypeScript (ترجیحا) یا JavaScript ایجاد کنید.
TypeScript توصیه میشود زیرا میتوانید از اتصالها برای اطمینان از اینکه دادههایی که برنامه شما برمیگرداند با انواع مورد انتظار پلتفرم مطابقت دارند، بهطور ایستا استفاده کنید.
برای جزئیات بیشتر در مورد API، به مرجع Local Home SDK API مراجعه کنید.
قطعههای زیر نشان میدهند که چگونه میتوانید برنامه تحقق محلی را مقداردهی اولیه کنید و کنترلکنندههای خود را متصل کنید.
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"); });
پروژه خود را ایجاد کنید
به منظور استقرار برنامه تحقق محلی خود، باید یک بسته جاوا اسکریپت برای کد خود و همه وابستگی های آن بسازید.
برای راهاندازی ساختار پروژه مناسب با پیکربندی باندلر دلخواه خود، از راهانداز پروژه برنامه تحقق محلی استفاده کنید.
قالب های پروژه
برای انتخاب پیکربندی باندلر، دستور 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 با پیکربندی بستهبندی وب :
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 با پیکربندی باندلر جمعآوری :
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 با پیکربندی بستهکننده بسته :
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
این اسکریپت نحو کد تایپ اسکریپت شما را تأیید می کند، آن را بدون تولید خروجی در دایرکتوری فرعی dist/
کامپایل می کند و تست های خودکار را از test.ts
اجرا می کند.
cd project-directory/ npm run start
در طول توسعه، این اسکریپت بستههای برنامه شما را برای محیطهای زمان اجرا Chrome و Node.js به صورت محلی ارائه میکند.
کنترل کننده IDENTIFY را پیاده سازی کنید
وقتی دستگاه Google Home یا Google Nest راهاندازی مجدد شود و دستگاههای محلی تأیید نشده (از جمله دستگاههای پایانی متصل به هاب) را ببیند، کنترلکننده IDENTIFY
فعال میشود. پلت فرم Local Home دستگاه های محلی را با استفاده از اطلاعات پیکربندی اسکن که قبلاً مشخص کرده اید اسکن می کند و با کنترل کننده IDENTIFY
شما با نتایج اسکن تماس می گیرد.
IdentifyRequest
از پلتفرم Local Home حاوی داده های اسکن یک نمونه LocalIdentifiedDevice
است. فقط یک نمونه device
پر شده است، بر اساس پیکربندی اسکن که دستگاه را کشف کرده است.
اگر نتایج اسکن با دستگاه شما مطابقت داشته باشد، کنترل کننده IDENTIFY
شما باید یک شی IdentifyResponsePayload
را برگرداند که شامل یک شی device
با فراداده خانه هوشمند (مانند انواع، ویژگی ها و وضعیت گزارش) است.
اگر verificationId
از پاسخ IDENTIFY
با یکی از مقادیر otherDeviceIds
برگردانده شده توسط پاسخ SYNC
مطابقت داشته باشد، Google یک ارتباط دستگاه ایجاد می کند.
مثال
قطعههای زیر نشان میدهند که چگونه میتوانید به ترتیب برای ادغام دستگاههای مستقل و هاب، کنترلکنندههای 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; };
دستگاه های پشت هاب را شناسایی کنید
اگر Google یک دستگاه هاب را شناسایی کند، هاب را به عنوان مجرای دستگاههای پایانی متصل به هاب در نظر میگیرد و تلاش میکند آن دستگاههای پایانی را تأیید کند.
برای فعال کردن Google برای تأیید وجود دستگاه هاب، این دستورالعملها را برای کنترلکننده IDENTIFY
خود دنبال کنید:
- اگر پاسخ
SYNC
شما شناسههای دستگاههای انتهایی محلی متصل به هاب را گزارش میدهد،isProxy
درIdentifyResponsePayload
به عنوانtrue
تنظیم کنید. - اگر پاسخ
SYNC
شما دستگاه هاب شما را گزارش نمی کند،isLocalOnly
به عنوانtrue
درIdentifyResponsePayload
تنظیم کنید. - فیلد
device.id
حاوی شناسه محلی دستگاه برای خود دستگاه هاب است.
پیادهسازی کنترلر REACHABLE_DEVICES (فقط ادغامهای هاب)
هدف REACHABLE_DEVICES
توسط Google ارسال میشود تا تأیید کند کدام دستگاههای نهایی را میتوان به صورت محلی کنترل کرد. این هدف هر بار که Google یک اسکن اکتشافی را اجرا می کند (تقریباً یک بار در دقیقه)، تا زمانی که مرکز آنلاین تشخیص داده شود، فعال می شود.
شما کنترل کننده REACHABLE_DEVICES
را مشابه کنترل کننده IDENTIFY
پیاده سازی می کنید، با این تفاوت که کنترل کننده شما باید شناسه های دستگاه اضافی را جمع آوری کند که توسط دستگاه پراکسی محلی (یعنی هاب) قابل دسترسی است. فیلد device.verificationId
حاوی شناسه محلی دستگاه برای دستگاه پایانی است که به هاب متصل است.
ReachableDevicesRequest
از پلتفرم Local Home حاوی نمونه ای از LocalIdentifiedDevice
است. از طریق این نمونه، می توانید شناسه دستگاه پراکسی و همچنین داده های نتایج اسکن را دریافت کنید.
کنترلکننده REACHABLE_DEVICES
شما باید یک شی ReachableDevicesPayload
را برگرداند که شامل یک شیء devices
است که حاوی آرایهای از مقادیر verificationId
است که نشاندهنده دستگاههای پایانی است که هاب کنترل میکند. مقادیر 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 را پیاده سازی کنید
کنترلر EXECUTE
شما در برنامه دستورات کاربر را پردازش می کند و از Local Home SDK برای دسترسی به دستگاه های هوشمند شما از طریق یک پروتکل موجود استفاده می کند.
پلت فرم Local Home همان بار ورودی را به عملکرد کنترل کننده EXECUTE
ارسال می کند که برای هدف EXECUTE
برای تحقق ابر شما. به همین ترتیب، کنترل کننده EXECUTE
شما داده های خروجی را با همان فرمت پردازش هدف EXECUTE
برمی گرداند. برای ساده سازی ایجاد پاسخ، می توانید از کلاس Execute.Response.Builder
که Local Home SDK ارائه می دهد استفاده کنید.
برنامه شما دسترسی مستقیم به آدرس 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
شما در برنامه درخواستهای کاربر را پردازش میکند و از Local Home SDK برای گزارش وضعیت دستگاههای هوشمند شما استفاده میکند.
پلتفرم Local Home همان بار درخواستی را به عملکرد کنترل کننده "QUERY" ارسال می کند که برای هدف QUERY
برای انجام ابر شما. به طور مشابه، کنترل کننده QUERY
شما داده ها را با همان قالبی که از پردازش هدف QUERY
برمی گرداند.
ارسال دستورات به دستگاه های پشت هاب
برای کنترل دستگاههای انتهایی در پشت یک هاب، ممکن است لازم باشد اطلاعات اضافی را در محموله فرمان خاص پروتکل ارسال شده به هاب ارائه دهید تا هاب تشخیص دهد که دستور برای کدام دستگاه است. در برخی موارد، این را می توان مستقیماً از مقدار device.id
استنباط کرد، اما وقتی اینطور نیست، باید این داده اضافی را به عنوان بخشی از قسمت customData
قرار دهید.
اگر برنامه خود را با استفاده از TypeScript ایجاد کرده اید، به یاد داشته باشید که برنامه خود را به جاوا اسکریپت کامپایل کنید. برای نوشتن کد می توانید از سیستم ماژول انتخابی خود استفاده کنید. مطمئن شوید که هدف شما توسط مرورگر کروم پشتیبانی می شود.