اقدامات خانه هوشمند خود را تقویت و ایمن کنید

1. قبل از شروع

Smart Home Actions از انواع دستگاه‌ها استفاده می‌کند تا به دستیار Google بفهماند چه دستور زبانی باید برای دستگاه استفاده شود. ویژگی های دستگاه قابلیت های یک نوع دستگاه را مشخص می کند. یک دستگاه حالت های هر ویژگی دستگاه را که به یک Action اضافه می شود به ارث می برد.

dc8dce0dea87cd5c.png

می توانید هر ویژگی پشتیبانی شده را به نوع دستگاه انتخابی خود متصل کنید تا عملکرد دستگاه های کاربران خود را سفارشی کنید. اگر می‌خواهید ویژگی‌های سفارشی را در Actions خود پیاده کنید که در حال حاضر در طرح دستگاه موجود نیستند، ویژگی‌های Modes و Toggles به کنترل تنظیمات خاص با نام سفارشی که شما تعریف می‌کنید اجازه می‌دهند.

فراتر از قابلیت کنترل اولیه ارائه شده توسط انواع و ویژگی ها، Smart Home API دارای ویژگی های اضافی برای بهبود تجربه کاربر است. پاسخ‌های خطا، بازخورد دقیق کاربر را زمانی که هدف‌ها موفق نمی‌شوند، ارائه می‌کنند. راستی‌آزمایی کاربر ثانویه این پاسخ‌ها را گسترش می‌دهد و امنیت بیشتری را به ویژگی دستگاه انتخابی شما اضافه می‌کند. با ارسال پاسخ‌های خطای خاص به بلوک‌های چالشی صادر شده از دستیار، اقدام خانه هوشمند شما می‌تواند برای تکمیل یک فرمان به مجوز بیشتری نیاز داشته باشد.

پیش نیازها

چیزی که خواهی ساخت

در این نرم افزار کد، یک ادغام خانه هوشمند از پیش ساخته شده را با Firebase اجرا می کنید، سپس یاد می گیرید که چگونه ویژگی های غیر استاندارد را برای اندازه بار و حالت توربو به واشر خانه هوشمند اضافه کنید. همچنین گزارش خطا و استثنا را پیاده‌سازی می‌کنید و یاد می‌گیرید که یک تأیید شفاهی برای روشن کردن واشر با استفاده از تأیید کاربر ثانویه اعمال کنید.

چیزی که یاد خواهید گرفت

  • چگونه ویژگی های Modes و Toggles را به Action خود اضافه کنید
  • نحوه گزارش خطاها و استثناها
  • نحوه اعمال تاییدیه کاربر ثانویه

آنچه شما نیاز دارید

2. شروع به کار

فعال کردن کنترل های فعالیت

برای استفاده از Google Assistant، باید داده‌های فعالیت خاصی را با Google به اشتراک بگذارید. دستیار Google برای عملکرد صحیح به این داده ها نیاز دارد. با این حال، نیاز به اشتراک گذاری داده ها مختص SDK نیست. برای اشتراک‌گذاری این داده‌ها، اگر قبلاً ندارید، یک حساب Google ایجاد کنید. می توانید از هر حساب Google استفاده کنید—نیازی نیست که حساب توسعه دهنده شما باشد.

صفحه Activity Controls را برای حساب Google که می‌خواهید با Assistant استفاده کنید، باز کنید.

اطمینان حاصل کنید که سوئیچ های زیر فعال هستند:

  • فعالیت وب و برنامه - علاوه بر این، حتماً کادر بررسی شامل سابقه و فعالیت Chrome از سایت‌ها، برنامه‌ها و دستگاه‌هایی که از خدمات Google استفاده می‌کنند را انتخاب کنید.
  • اطلاعات دستگاه
  • فعالیت صوتی و صوتی

یک پروژه Actions ایجاد کنید

  1. به Actions on Google Developer Console بروید.
  2. پروژه جدید را کلیک کنید، یک نام برای پروژه وارد کنید و روی ایجاد پروژه کلیک کنید.

3d6b68ca79afd54c.png

برنامه خانه هوشمند را انتخاب کنید

در صفحه نمای کلی در کنسول اقدامات، خانه هوشمند را انتخاب کنید.

2fa4988f44f8914b.png

کارت تجربه خانه هوشمند را انتخاب کنید، روی Start Building کلیک کنید و سپس به کنسول پروژه خود هدایت خواهید شد.

Firebase CLI را نصب کنید

رابط خط فرمان Firebase (CLI) به شما این امکان را می دهد که برنامه های وب خود را به صورت محلی ارائه دهید و برنامه وب خود را در میزبانی Firebase مستقر کنید.

برای نصب CLI، دستور npm زیر را از ترمینال اجرا کنید:

npm install -g firebase-tools

برای تأیید اینکه CLI به درستی نصب شده است، اجرا کنید:

firebase --version

با اجرای زیر Firebase CLI را با حساب Google خود مجاز کنید:

firebase login

HomeGraph API را فعال کنید

HomeGraph API ذخیره و پرس و جو از دستگاه ها و وضعیت آنها را در نمودار اصلی کاربر فعال می کند. برای استفاده از این API، ابتدا باید کنسول Google Cloud را باز کرده و HomeGraph API را فعال کنید .

در کنسول Google Cloud، مطمئن شوید که پروژه‌ای را انتخاب کنید که با Actions <project-id>. سپس، در صفحه کتابخانه API برای HomeGraph API، روی فعال کردن کلیک کنید.

ee198858a6eac112.png

3. برنامه استارتر را اجرا کنید

اکنون که محیط توسعه خود را راه‌اندازی می‌کنید، می‌توانید پروژه راه‌اندازی را اجرا کنید تا تأیید کنید همه چیز به درستی پیکربندی شده است.

کد منبع را دریافت کنید

برای دانلود نمونه این کد لبه روی دستگاه توسعه خود، روی لینک زیر کلیک کنید:

یا می توانید مخزن GitHub را از خط فرمان کلون کنید:

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

فایل فشرده دانلود شده را باز کنید.

در مورد پروژه

پروژه شروع کننده شامل زیر شاخه های زیر است:

  • public: رابط کاربری frontend برای کنترل و نظارت آسان بر وضعیت واشر هوشمند.
  • functions: یک سرویس ابری کاملاً پیاده‌سازی شده که واشر هوشمند را با توابع Cloud برای پایگاه داده بیدرنگ Firebase و Firebase مدیریت می‌کند.

تکمیل ابر ارائه شده شامل توابع زیر در index.js است:

  • fakeauth : نقطه پایانی مجوز برای پیوند دادن حساب
  • faketoken : نقطه پایانی رمز برای پیوند دادن حساب
  • smarthome : نقطه پایان تحقق هدف خانه هوشمند
  • reportstate : API Graph Home را در تغییرات وضعیت دستگاه فراخوانی می کند
  • requestsync : به روز رسانی دستگاه کاربر را بدون نیاز به پیوند مجدد حساب فعال می کند

به Firebase متصل شوید

به فهرست راهنمای washer-start بروید، سپس Firebase CLI را با پروژه Actions خود راه اندازی کنید:

cd washer-start
firebase use <project-id>

پیکربندی پروژه Firebase

یک پروژه Firebase را راه اندازی کنید.

firebase init

ویژگی های CLI، پایگاه داده بیدرنگ ، توابع ، و ویژگی میزبانی که شامل میزبانی Firebase است را انتخاب کنید.

? Which Firebase CLI features do you want to set up for this directory? Press Space to select features, then
 Enter to confirm your choices.
❯◉ Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision default instance
 ◯ Firestore: Configure security rules and indexes files for Firestore
 ◉ Functions: Configure a Cloud Functions directory and its files
 ◉ Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys
 ◯ Hosting: 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

با این کار API ها و ویژگی های لازم برای پروژه شما مقداردهی اولیه می شود.

هنگامی که از شما خواسته شد، پایگاه داده Realtime را مقداردهی اولیه کنید. می توانید از مکان پیش فرض برای نمونه پایگاه داده استفاده کنید.

? 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

اگر پروژه خود را مجدداً مقداردهی اولیه می کنید، وقتی از شما پرسیده شد که آیا می خواهید یک پایگاه کد را مقداردهی اولیه یا بازنویسی کنید، گزینه Overwrite را انتخاب کنید.

? 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

اگر پروژه خود را مجدداً راه اندازی می کنید، وقتی از شما پرسیده شد که آیا می خواهید توابع/.gitignore را مقداردهی اولیه یا بازنویسی کنید، گزینه No را انتخاب کنید.

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

در نهایت، تنظیمات میزبانی خود را برای استفاده از دایرکتوری public در کد پروژه پیکربندی کنید و از فایل index.html موجود استفاده کنید. هنگامی که از ESLint خواسته شد گزینه No را انتخاب کنید.

? What do you want to use as your public directory?
public

? Configure as a single-page app (rewrite all urls to /index.html)?
Yes

? Set up automatic builds and deploys with GitHub?
No

? File public/index.html already exists. Overwrite?
 No

اگر ESLint به طور تصادفی فعال شد، دو روش برای غیرفعال کردن آن وجود دارد:

  1. با استفاده از رابط کاربری گرافیکی، به پوشه ../functions زیر پروژه رفته، فایل مخفی .eslintrc.js را انتخاب کرده و آن را حذف کنید. آن را با نام مشابه .eslintrc.json اشتباه نکنید.
  2. با استفاده از خط فرمان:
    cd functions
    rm .eslintrc.js
    

در Firebase مستقر شوید

اکنون که وابستگی ها را نصب کرده اید و پروژه خود را پیکربندی کرده اید، برای اولین بار آماده اجرای برنامه هستید.

firebase deploy

این خروجی کنسولی است که باید ببینید:

...

✔ Deploy complete!

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

این دستور یک برنامه وب را به همراه چندین تابع Cloud برای Firebase مستقر می کند.

برای مشاهده برنامه وب ، URL میزبانی را در مرورگر خود باز کنید ( https://<project-id>.web.app ). رابط زیر را خواهید دید:

5845443e94705557.png

این رابط کاربری وب نشان دهنده یک پلت فرم شخص ثالث برای مشاهده یا تغییر وضعیت دستگاه است. برای شروع پر کردن پایگاه داده خود با اطلاعات دستگاه، روی UPDATE کلیک کنید. هیچ تغییری در صفحه مشاهده نمی کنید، اما وضعیت فعلی ماشین لباسشویی شما در پایگاه داده ذخیره می شود.

اکنون زمان آن رسیده است که سرویس ابری را با استفاده از کنسول Actions به Google Assistant متصل کنید.

پروژه کنسول Actions خود را پیکربندی کنید

در قسمت نمای کلی > Build your Action ، Add Action(s) را انتخاب کنید. URL را برای عملکرد ابری خود وارد کنید که اهداف خانه هوشمند را برآورده می کند و روی ذخیره کلیک کنید.

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

9d7b223427f587ca.png

در برگه Develop > Invocation ، یک نام نمایشی برای Action خود اضافه کنید و روی Save کلیک کنید. این نام در برنامه Google Home ظاهر می شود.

774d0c40c351c7da.png

a8c4673eb11d76ee.png

برای فعال کردن پیوند حساب، گزینه Develop > Account linking را در ناوبری سمت چپ انتخاب کنید. از این تنظیمات پیوند حساب استفاده کنید:

شناسه مشتری

ABC123

راز مشتری

DEF456

URL مجوز

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

نشانی اینترنتی رمز

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

9730d20b90bcc038.png

روی Save کلیک کنید تا پیکربندی پیوند حساب خود را ذخیره کنید، سپس روی Test کلیک کنید تا آزمایش روی پروژه شما فعال شود.

ee0547f05b5efd98.png

شما به شبیه ساز هدایت خواهید شد. اگر « Test now enabled » را نمی‌بینید، روی Reset Test کلیک کنید تا تأیید شود که آزمایش فعال است.

d0495810dbadf059.png

برای آزمایش اکشن خانه هوشمند خود، باید پروژه خود را با یک حساب Google مرتبط کنید. این امکان آزمایش از طریق سطوح دستیار Google و برنامه Google Home را فراهم می کند که به سیستم یک حساب وارد شده اند.

  1. در تلفن خود، تنظیمات دستیار Google را باز کنید. توجه داشته باشید که باید با همان حساب کاربری در کنسول وارد شوید.
  2. به Google Assistant > Settings > Home Control (در زیر Assistant) بروید.
  3. روی نماد جستجو در بالا سمت راست کلیک کنید.
  4. برنامه آزمایشی خود را با استفاده از پیشوند [test] جستجو کنید تا برنامه آزمایشی خاص خود را پیدا کنید.
  5. آن مورد را انتخاب کنید. سپس Google Assistant با سرویس شما احراز هویت می‌کند و یک درخواست SYNC ارسال می‌کند و از سرویس شما می‌خواهد فهرستی از دستگاه‌ها را برای کاربر ارائه دهد.

برنامه Google Home را باز کنید و بررسی کنید که می‌توانید دستگاه لباسشویی خود را ببینید.

ae252220753726f6.png

بررسی کنید که می‌توانید با استفاده از دستورات صوتی در برنامه Google Home ماشین لباسشویی را کنترل کنید. همچنین باید تغییر وضعیت دستگاه را در رابط کاربری وب جلویی اجرای ابری خود مشاهده کنید.

اکنون که یک واشر اصلی به کار گرفته اید، می توانید حالت های موجود در دستگاه خود را سفارشی کنید.

4. حالت ها را اضافه کنید

ویژگی action.devices.traits.Modes دستگاه را قادر می‌سازد تا تعداد دلخواه تنظیمات را برای یک حالت داشته باشد که تنها یکی از آن‌ها را می‌توان در هر زمان تنظیم کرد. برای تعیین اندازه بار لباسشویی، حالتی به ماشین لباسشویی اضافه می کنید: کوچک، متوسط ​​یا بزرگ.

به روز رسانی پاسخ SYNC

شما باید اطلاعات مربوط به ویژگی جدید را به پاسخ SYNC خود در functions/index.js اضافه کنید. این داده در آرایه traits ظاهر می‌شود و شیء را همانطور که در قطعه کد زیر نشان داده شده است attributes .

index.js

app.onSync(body => {
  return {
    requestId: 'ff36a3cc-ec34-11e6-b1a0-64510650abcf',
    payload: {
      agentUserId: USER_ID,
      devices: [{
        id: 'washer',
        type: 'action.devices.types.WASHER',
        traits: [
          'action.devices.traits.OnOff',
          'action.devices.traits.StartStop',
          'action.devices.traits.RunCycle',
          // Add Modes trait
          'action.devices.traits.Modes',
        ],
        name: { ... },
        deviceInfo: { ... },
        attributes: {
          pausable: true,
          //Add availableModes
          availableModes: [{
            name: 'load',
            name_values: [{
              name_synonym: ['load'],
              lang: 'en',
            }],
            settings: [{
              setting_name: 'small',
              setting_values: [{
                setting_synonym: ['small'],
                lang: 'en',
              }]
            }, {
              setting_name: 'medium',
              setting_values: [{
                setting_synonym: ['medium'],
                lang: 'en',
              }]
            }, {
              setting_name: 'large',
              setting_values: [{
                setting_synonym: ['large'],
                lang: 'en',
              }]
            }],
            ordered: true,
          }],
        },
      }],
    },
  };
});

دستورات جدید EXECUTE intent اضافه کنید

در هدف EXECUTE ، دستور action.devices.commands.SetModes را همانطور که در قطعه کد زیر نشان داده شده است اضافه کنید.

index.js

const updateDevice = async (execution,deviceId) => {
  const {params,command} = execution;
  let state, ref;
  switch (command) {
    case 'action.devices.commands.OnOff':
      state = {on: params.on};
      ref = firebaseRef.child(deviceId).child('OnOff');
      break;
    case 'action.devices.commands.StartStop':
      state = {isRunning: params.start};
      ref = firebaseRef.child(deviceId).child('StartStop');
      break;
    case 'action.devices.commands.PauseUnpause':
      state = {isPaused: params.pause};
      ref = firebaseRef.child(deviceId).child('StartStop');
      Break;
    // Add SetModes command
    case 'action.devices.commands.SetModes':
      state = {load: params.updateModeSettings.load};
      ref = firebaseRef.child(deviceId).child('Modes');
      break;
}

پاسخ QUERY را به روز کنید

در مرحله بعد، پاسخ QUERY خود را برای گزارش وضعیت فعلی ماشین لباسشویی به روز کنید.

تغییرات به روز شده را به توابع queryFirebase و queryDevice اضافه کنید تا وضعیت ذخیره شده در پایگاه داده Realtime را بدست آورید.

index.js

const queryFirebase = async (deviceId) => {
  const snapshot = await firebaseRef.child(deviceId).once('value');
  const snapshotVal = snapshot.val();
  return {
    on: snapshotVal.OnOff.on,
    isPaused: snapshotVal.StartStop.isPaused,
    isRunning: snapshotVal.StartStop.isRunning,
    // Add Modes snapshot
    load: snapshotVal.Modes.load,
  };
}

const queryDevice = async (deviceId) => {
  const data = await queryFirebase(deviceId);
  return {
    on: data.on,
    isPaused: data.isPaused,
    isRunning: data.isRunning,
    currentRunCycle: [{ ... }],
    currentTotalRemainingTime: 1212,
    currentCycleRemainingTime: 301,
    // Add currentModeSettings
    currentModeSettings: {
      load: data.load,
    },
  };
};

به روز رسانی وضعیت گزارش

در نهایت، عملکرد reportstate خود را به روز کنید تا تنظیمات بار فعلی ماشین لباسشویی را به Home Graph گزارش کنید.

index.js

const requestBody = {
  requestId: 'ff36a3cc', /* Any unique ID */
  agentUserId: USER_ID,
  payload: {
    devices: {
      states: {
        /* Report the current state of your washer */
        [context.params.deviceId]: {
          on: snapshot.OnOff.on,
          isPaused: snapshot.StartStop.isPaused,
          isRunning: snapshot.StartStop.isRunning,
          // Add currentModeSettings
          currentModeSettings: {
            load: snapshot.Modes.load,
          },
        },
      },
    },
  },
};

در Firebase مستقر شوید

دستور زیر را برای پیاده سازی اکشن به روز شده اجرا کنید:

firebase deploy --only functions

پس از تکمیل استقرار، به رابط کاربری وب بروید و روی Refresh کلیک کنید ae8d3b25777a5e30.png دکمه در نوار ابزار این یک درخواست همگام سازی را راه اندازی می کند تا دستیار داده های پاسخ SYNC به روز شده را دریافت کند.

bf4f6a866160a982.png

اکنون می توانید دستور تنظیم حالت واشر را بدهید، مانند:

"Hey Google، بار لباسشویی را روی بزرگ تنظیم کنید."

علاوه بر این، می توانید سوالاتی در مورد ماشین لباسشویی خود بپرسید، مانند:

"Hey Google، بار لباسشویی چقدر است؟"

5. ضامن ها را اضافه کنید

ویژگی action.devices.traits.Toggles جنبه های نامگذاری شده یک دستگاه را نشان می دهد که حالت درست یا نادرست دارند، مانند اینکه آیا واشر در حالت توربو قرار دارد.

به روز رسانی پاسخ SYNC

در پاسخ SYNC ، باید اطلاعاتی درباره ویژگی دستگاه جدید اضافه کنید. همانطور که در قطعه کد زیر نشان داده شده است، در آرایه traits ظاهر می شود و شیء attributes .

index.js

app.onSync(body => {
  return {
    requestId: 'ff36a3cc-ec34-11e6-b1a0-64510650abcf',
    payload: {
      agentUserId: USER_ID,
      devices: [{
        id: 'washer',
        type: 'action.devices.types.WASHER',
        traits: [
          'action.devices.traits.OnOff',
          'action.devices.traits.StartStop',
          'action.devices.traits.RunCycle',
          'action.devices.traits.Modes',
          // Add Toggles trait
          'action.devices.traits.Toggles',
        ],
        name: { ... },
        deviceInfo: { ... },
        attributes: {
          pausable: true,
          availableModes: [{
            name: 'load',
            name_values: [{
              name_synonym: ['load'],
              lang: 'en'
            }],
            settings: [{ ... }],
            ordered: true,
          }],
          //Add availableToggles
          availableToggles: [{
            name: 'Turbo',
            name_values: [{
              name_synonym: ['turbo'],
              lang: 'en',
            }],
          }],
        },
      }],
    },
  };
});

دستورات جدید EXECUTE intent اضافه کنید

در هدف EXECUTE ، دستور action.devices.commands.SetToggles را همانطور که در قطعه کد زیر نشان داده شده است اضافه کنید.

index.js

const updateDevice = async (execution,deviceId) => {
  const {params,command} = execution;
  let state, ref;
  switch (command) {
    case 'action.devices.commands.OnOff':
      state = {on: params.on};
      ref = firebaseRef.child(deviceId).child('OnOff');
      break;
    case 'action.devices.commands.StartStop':
      state = {isRunning: params.start};
      ref = firebaseRef.child(deviceId).child('StartStop');
      break;
    case 'action.devices.commands.PauseUnpause':
      state = {isPaused: params.pause};
      ref = firebaseRef.child(deviceId).child('StartStop');
      break;
    case 'action.devices.commands.SetModes':
      state = {load: params.updateModeSettings.load};
      ref = firebaseRef.child(deviceId).child('Modes');
      break;
    // Add SetToggles command
    case 'action.devices.commands.SetToggles':
      state = {Turbo: params.updateToggleSettings.Turbo};
      ref = firebaseRef.child(deviceId).child('Toggles');
      break;
  }

پاسخ QUERY را به روز کنید

در نهایت، باید پاسخ QUERY خود را برای گزارش حالت توربوی ماشین لباسشویی به روز کنید. تغییرات به روز شده را به توابع queryFirebase و queryDevice اضافه کنید تا وضعیت تغییر حالت ذخیره شده در پایگاه داده Realtime را بدست آورید.

index.js

const queryFirebase = async (deviceId) => {
  const snapshot = await firebaseRef.child(deviceId).once('value');
  const snapshotVal = snapshot.val();
  return {
    on: snapshotVal.OnOff.on,
    isPaused: snapshotVal.StartStop.isPaused,
    isRunning: snapshotVal.StartStop.isRunning,
    load: snapshotVal.Modes.load,
    // Add Toggles snapshot
    Turbo: snapshotVal.Toggles.Turbo,
  };
}

const queryDevice = async (deviceId) => {
  const data = queryFirebase(deviceId);
  return {
    on: data.on,
    isPaused: data.isPaused,
    isRunning: data.isRunning,
    currentRunCycle: [{ ... }],
    currentTotalRemainingTime: 1212,
    currentCycleRemainingTime: 301,
    currentModeSettings: {
      load: data.load,
    },
    // Add currentToggleSettings
    currentToggleSettings: {
      Turbo: data.Turbo,
    },
  };
};

به روز رسانی وضعیت گزارش

در نهایت، عملکرد reportstate خود را به روز کنید تا به Home Graph گزارش دهید که آیا واشر روی توربو تنظیم شده است.

index.js

const requestBody = {
  requestId: 'ff36a3cc', /* Any unique ID */
  agentUserId: USER_ID,
  payload: {
    devices: {
      states: {
        /* Report the current state of your washer */
        [context.params.deviceId]: {
          on: snapshot.OnOff.on,
          isPaused: snapshot.StartStop.isPaused,
          isRunning: snapshot.StartStop.isRunning,
          currentModeSettings: {
            load: snapshot.Modes.load,
          },
          // Add currentToggleSettings
          currentToggleSettings: {
            Turbo: snapshot.Toggles.Turbo,
          },
        },
      },
    },
  },
};

در Firebase مستقر شوید

دستور زیر را برای استقرار توابع به روز شده اجرا کنید:

firebase deploy --only functions

روی Refresh کلیک کنید ae8d3b25777a5e30.png دکمه در رابط کاربری وب برای راه اندازی درخواست همگام سازی پس از تکمیل استقرار.

اکنون می توانید با گفتن این جمله دستور دهید که واشر را روی حالت توربو قرار دهید:

"Hey Google، توربو را برای ماشین لباسشویی روشن کن."

همچنین می توانید با پرسیدن زیر بررسی کنید که آیا ماشین لباسشویی شما قبلاً در حالت توربو قرار دارد:

"Hey Google، آیا ماشین لباسشویی من در حالت توربو است؟"

6. گزارش خطاها و استثناها

رسیدگی به خطا در خانه هوشمند Action شما را قادر می‌سازد زمانی که مشکلاتی باعث می‌شود پاسخ‌های EXECUTE و QUERY با شکست مواجه شوند، به کاربران گزارش دهید. اعلان ها هنگام تعامل با دستگاه هوشمند و Action شما، تجربه کاربری مثبت تری را برای کاربران شما ایجاد می کنند.

هر زمان که یک درخواست EXECUTE یا QUERY با شکست مواجه شد، Action شما باید یک کد خطا را برگرداند. برای مثال، اگر می‌خواهید زمانی که کاربر می‌خواهد واشر را با درب باز راه‌اندازی کند، خطایی ایجاد کنید، پاسخ EXECUTE شما مانند قطعه کد زیر خواهد بود:

{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "commands": [
      {
        "ids": [
          "456"
        ],
        "status": "ERROR",
        "errorCode": "deviceLidOpen"
      }
    ]
  }
}

اکنون، هنگامی که کاربر می‌خواهد واشر را راه‌اندازی کند، دستیار با گفتن این جمله پاسخ می‌دهد:

"درب ماشین لباسشویی باز است. لطفاً آن را ببندید و دوباره امتحان کنید."

استثناها مشابه خطاها هستند، اما زمانی را نشان می دهند که یک هشدار با یک فرمان مرتبط است، که ممکن است اجرای موفقیت آمیز را مسدود کند یا نکند. یک استثنا می تواند اطلاعات مرتبطی را با استفاده از ویژگی StatusReport ارائه دهد، مانند سطح باتری یا تغییر وضعیت اخیر. کدهای استثنای غیرمسدود همراه با وضعیت SUCCESS برگردانده می شوند، در حالی که کدهای استثنا مسدود کننده با وضعیت EXCEPTIONS برگردانده می شوند.

یک نمونه پاسخ با یک استثنا در قطعه کد زیر است:

{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "commands": [{
      "ids": ["123"],
      "status": "SUCCESS",
      "states": {
        "online": true,
        "isPaused": false,
        "isRunning": false,
        "exceptionCode": "runCycleFinished"
      }
    }]
  }
}

دستیار در پاسخ می گوید:

"کارکرد ماشین لباسشویی به پایان رسیده است."

برای افزودن گزارش خطا برای واشر خود، functions/index.js را باز کنید و تعریف کلاس خطا را همانطور که در قطعه کد زیر مشاهده می کنید اضافه کنید:

index.js

app.onQuery(async (body) => {...});

// Add SmartHome error handling
class SmartHomeError extends Error {
  constructor(errorCode, message) {
    super(message);
    this.name = this.constructor.name;
    this.errorCode = errorCode;
  }
}

برای بازگرداندن کد خطا و وضعیت خطا، پاسخ اجرا را به روز کنید:

index.js

const executePromises = [];
const intent = body.inputs[0];
for (const command of intent.payload.commands) {
  for (const device of command.devices) {
    for (const execution of command.execution) {
      executePromises.push( ... )
          //Add error response handling
          .catch((error) => {
            functions.logger.error('EXECUTE', device.id, error);
            result.ids.push(device.id);
            if(error instanceof SmartHomeError) {
              result.status = 'ERROR';
              result.errorCode = error.errorCode;
            }
          })
      );
    }
  }
}

اکنون دستیار می‌تواند هر کد خطایی را که گزارش می‌کنید به کاربران شما اطلاع دهد. در بخش بعدی یک مثال خاص را مشاهده خواهید کرد.

7. تأیید کاربر ثانویه را اضافه کنید

اگر دستگاه شما دارای حالت‌هایی است که باید ایمن شوند یا باید به گروه خاصی از کاربران مجاز محدود شوند، مانند به‌روزرسانی نرم‌افزار یا قطع کردن قفل، باید تأیید کاربر ثانویه را در Action خود اجرا کنید.

می‌توانید تأیید کاربر ثانویه را بر روی همه انواع و ویژگی‌های دستگاه پیاده‌سازی کنید، و سفارشی کنید که آیا چالش امنیتی هر بار رخ می‌دهد یا نیاز به رعایت معیارهای خاصی است.

سه نوع چالش پشتیبانی شده وجود دارد:

  • No challenge — درخواست و پاسخی که از چالش احراز هویت استفاده نمی کند (این رفتار پیش فرض است)
  • ackNeeded - تأیید کاربر ثانویه که نیاز به تأیید صریح دارد (بله یا خیر)
  • pinNeeded - تأیید کاربر ثانویه که به شماره شناسایی شخصی (PIN) نیاز دارد.

برای این کد لبه، یک چالش ackNeeded را به فرمان روشن کردن واشر اضافه کنید و در صورت شکست چالش تأیید ثانویه، یک خطا را بازگردانید.

functions/index.js را باز کنید و یک تعریف کلاس خطا اضافه کنید که کد خطا و نوع چالش را همانطور که در قطعه کد زیر مشاهده می‌کنید برمی‌گرداند:

index.js

class SmartHomeError extends Error { ... }

// Add secondary user verification error handling
class ChallengeNeededError extends SmartHomeError {
  /**
   * Create a new ChallengeNeededError
   * @param {string} suvType secondary user verification challenge type
   */
  constructor(suvType) {
    super('challengeNeeded', suvType);
    this.suvType = suvType;
  }
}

همچنین باید پاسخ اجرا را به روز کنید تا خطای challengeNeeded را به صورت زیر برگردانید:

index.js

const executePromises = [];
const intent = body.inputs[0];
for (const command of intent.payload.commands) {
  for (const device of command.devices) {
    for (const execution of command.execution) {
      executePromises.push( ... )
          .catch((error) => {
            functions.logger.error('EXECUTE', device.id, error);
            result.ids.push(device.id);
            if(error instanceof SmartHomeError) {
              result.status = 'ERROR';
              result.errorCode = error.errorCode;
              //Add error response handling
              if(error instanceof ChallengeNeededError) {
                result.challengeNeeded = {
                  type: error.suvType
                };
              }
            }
          })
      );
    }
  }
}

در نهایت، updateDevice را تغییر دهید تا برای روشن یا خاموش کردن واشر به تأیید صریح نیاز داشته باشید.

index.js

const updateDevice = async (execution,deviceId) => {
  const {challenge,params,command} = execution; //Add secondary user challenge
  let state, ref;
  switch (command) {
    case 'action.devices.commands.OnOff':
      //Add secondary user verification challenge
      if (!challenge || !challenge.ack) {
        throw new ChallengeNeededError('ackNeeded');
      }
      state = {on: params.on};
      ref = firebaseRef.child(deviceId).child('OnOff');
      break;
    ...
  }

  return ref.update(state)
      .then(() => state);
};

در Firebase مستقر شوید

دستور زیر را برای استقرار تابع به روز شده اجرا کنید:

firebase deploy --only functions

پس از استقرار کد به‌روزرسانی شده، وقتی از «دستیار» می‌خواهید لباسشویی خود را روشن یا خاموش کند، باید به صورت شفاهی این عمل را تأیید کنید، مانند این:

شما: "Hey Google، ماشین لباسشویی را روشن کن."

دستیار: "آیا مطمئن هستید که می خواهید ماشین لباسشویی را روشن کنید؟"

شما: "بله."

همچنین می‌توانید با باز کردن گزارش‌های Firebase، پاسخ دقیقی برای هر مرحله از جریان تأیید کاربر ثانویه ببینید.

289dbe48f4bb8106.png

8. تبریک می گویم

674c4f4392e98c1.png

تبریک می گویم! شما ویژگی‌های اقدامات خانه هوشمند را از طریق ویژگی‌های Modes و Toggles گسترش دادید و اجرای آنها را از طریق تأیید کاربر ثانویه ایمن کردید.

بیشتر بدانید

در اینجا ایده هایی وجود دارد که می توانید برای عمیق تر شدن آنها پیاده سازی کنید:

  • قابلیت های اجرای محلی را به دستگاه های خود اضافه کنید.
  • برای تغییر وضعیت دستگاه خود از یک نوع چالش تأیید کاربر ثانویه دیگر استفاده کنید.
  • برای به‌روزرسانی پویا، پاسخ QUERY صفت RunCycle را به‌روزرسانی کنید.
  • این نمونه GitHub را کاوش کنید.