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

1. قبل از شروع

ادغام‌های Cloud-to-Cloud از انواع دستگاه استفاده می‌کنند تا به دستیار Google اطلاع دهد که چه دستور زبانی باید برای دستگاه استفاده شود. ویژگی های دستگاه قابلیت های یک نوع دستگاه را مشخص می کند. یک دستگاه حالات هر ویژگی دستگاه را که به یک ادغام اضافه شده است به ارث می برد.

dc8dce0dea87cd5c.png

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

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

پیش نیازها

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

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

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

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

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

2. شروع به کار

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

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

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

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

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

یک پروژه ادغام ابر به ابر ایجاد کنید

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

نام پروژه

Cloud-to-cloud Integration را انتخاب کنید

در Project Home در Developer Console، Add cloud-to-cloud integration را در Cloud-to-cloud انتخاب کنید.

ادغام ابر به ابر را اضافه کنید

Firebase CLI را نصب کنید

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

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

npm install -g firebase-tools

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

firebase --version

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

firebase login

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

  1. به Firebase بروید.
  2. روی ایجاد پروژه کلیک کنید و نام پروژه خود را وارد کنید.
  3. چک باکس توافقنامه را علامت بزنید و روی Continue کلیک کنید. اگر کادر تأیید توافق وجود ندارد، می‌توانید این مرحله را رد کنید.
    پروژه Firebase را ایجاد کنید
  4. پس از ایجاد پروژه Firebase، شناسه پروژه را پیدا کنید. به نمای کلی پروژه بروید و روی نماد تنظیمات > تنظیمات پروژه کلیک کنید.
    تنظیمات پروژه را باز کنید
  5. پروژه شما در زیر تب General فهرست شده است.
    تنظیمات کلی پروژه

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

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

در کنسول Google Cloud، مطمئن شوید که پروژه‌ای را انتخاب کنید که با Actions <firebase-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 را با پروژه ادغام خود راه اندازی کنید:

cd washer-start
firebase use <firebase-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/<firebase-project-id>/overview
Hosting URL: https://<firebase-project-id>.web.app

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

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

5845443e94705557.png

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

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

پروژه Developer Console خود را پیکربندی کنید

در تب Develop ، یک نام نمایشی برای تعامل خود اضافه کنید. این نام در برنامه Google Home ظاهر می شود.

یک نام نمایشی اضافه کنید

در زیر نام تجاری برنامه ، یک فایل png برای نماد برنامه با اندازه 144 x 144 پیکسل و با نام آپلود کنید .png .

یک نماد برنامه اضافه کنید

برای فعال کردن پیوند حساب از این تنظیمات پیوند حساب استفاده کنید:

شناسه مشتری

ABC123

راز مشتری

DEF456

URL مجوز

https://us-central1-
.cloudfunctions.net/fakeauth

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

https://us-central1-
.cloudfunctions.net/faketoken

URL های پیوند دهنده حساب را به روز کنید

در زیر نشانی اینترنتی تکمیل ابر ، نشانی اینترنتی عملکرد ابری خود را وارد کنید که اهداف خانه هوشمند را برآورده می‌کند.

https://us-central1- -cloudfunctions.net/smarthome https://us-central1- -cloudfunctions.net/smarthome

URL تابع ابری را اضافه کنید

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

ادغام ابر به ابر خود را آزمایش کنید

اکنون می توانید اجرای وبکهک های لازم برای اتصال وضعیت دستگاه به دستیار را شروع کنید.

برای آزمایش ادغام Cloud-to-Cloud خود، باید پروژه خود را با یک حساب 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 اضافه کنید

همانطور که در قطعه کد زیر نشان داده شده است، در 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. گزارش خطاها و استثنائات

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

هر زمان که یک درخواست EXECUTE یا QUERY با شکست مواجه شد، ادغام شما باید یک کد خطا را برگرداند. برای مثال، اگر می‌خواهید زمانی که کاربر می‌خواهد واشر را با درب باز راه‌اندازی کند، خطایی ایجاد کنید، پاسخ 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(
        updateDevice(execution, device.id)
        .then((data) => {
          ...
        })
        //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. تأیید کاربر ثانویه را اضافه کنید

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

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

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

  • 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(

        updateDevice(execution, device.id)
        .then((data) => {
          ...
        })
        .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

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

بیشتر بدانید

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

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