歡迎使用 Google Home 開發人員中心,探索全新功能,瞭解如何開發智慧住宅動作。注意:請繼續在「動作」控制台中建立動作。

將智慧住宅裝置連結至 Google 助理

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

1. 事前準備

物聯網 (IoT) 開發人員可以打造智慧型住宅動作,讓使用者透過 Google Home 應用程式的觸控設定和透過 Google 助理的語音指令控制裝置。

79266e5f45e6ae20.gif

智慧型住宅動作會依賴住家圖表來提供住家和裝置的相關內容比對資料,並建立住家的邏輯地圖。因此,「Google 助理」得以根據使用者的住家位置,更自然地掌握使用者的要求。舉例來說,「住家圖」可以儲存客廳的概念,其中包含多種製造商裝置的多種類型裝置,例如溫度控制器、檯燈、風扇和吸塵器。

d009cef0f903d284.jpeg

必要條件

建構項目

在本程式碼研究室中,您將發布管理虛擬智慧型洗衣機的雲端服務,然後打造智慧型居家動作並將其連結至 Google 助理。

課程內容

  • 如何部署智慧住宅雲端服務
  • 如何將服務與 Google 助理建立連結
  • 如何將裝置狀態變更發布至 Google

軟硬體需求

2. 開始使用

啟用活動控制項

如要使用 Google 助理,必須將特定活動資料提供給 Google。Google 助理需要這項資料才能正常運作;但並非 SDK 以外的需求條件。如要分享這項資料,請建立 Google 帳戶 (如果還沒有帳戶)。您可以使用任何 Google 帳戶,例如您的開發人員帳戶。

針對要與 Google 助理搭配使用的 Google 帳戶,開啟活動控制項頁面

確認下列切換開關已啟用:

  • 網路和應用程式活動:此外,請務必勾選 [包括 Chrome 歷史記錄以及採用 Google 服務的網站、應用程式和裝置中的活動記錄] 核取方塊。
  • 裝置資訊
  • 語音和音訊活動

建立動作專案

  1. 前往 Actions on Google Developer Console
  2. 按一下「New Project」,輸入專案名稱,然後按一下「CREATE PROJECT」

3D6b68ca79afd54c.png

選取智慧住宅應用程式

在動作控制台的總覽畫面上,選取 [智慧型住宅]

2fa4988f44f8914b.png

選擇「智慧型住宅」體驗資訊卡,然後按一下「開始建立」,系統會將您帶往專案控制台。

安裝 Firebase CLI

Firebase 指令列介面 (CLI) 可讓您在本機提供網頁應用程式,並將網頁應用程式部署至 Firebase 託管。

如要安裝 CLI,請在終端機中執行下列 npm 指令:

npm install -g firebase-tools

如要確認 CLI 是否已正確安裝,請執行下列指令:

firebase --version

執行下列指令,使用 Google 帳戶授權 Firebase CLI:

firebase login

3. 執行入門應用程式

開發環境設定完畢後,您可以部署範例專案,確認所有設定皆正確無誤。

取得原始碼

點選下列連結,在開發機器上下載本程式碼研究室的範例:

...您也可以透過指令列複製 GitHub 存放區:

git clone https://github.com/googlecodelabs/smarthome-washer.git

關於專案

範例專案包含下列子目錄:

  • public:前端 UI,可輕鬆控制及監控智慧型洗衣機的狀態。
  • functions:功能齊全的雲端服務,透過 Cloud Functions for Firebase 和 Firebase 即時資料庫管理智慧型洗衣機。

連結至 Firebase

前往 washer-start 目錄,然後使用動作專案設定 Firebase CLI:

cd washer-start
firebase use <project-id>

設定 Firebase 專案

初始化 Firebase 專案。

firebase init

選取 [資料庫]、[函式] 和 [託管] CLI 功能。

? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then
 Enter to confirm your choices. 
❯◉ Database: Configure Firebase Realtime Database and deploy rules
 ◯ Firestore: Deploy rules and create indexes for Firestore
 ◉ Functions: Configure and deploy Cloud Functions
 ◉ Hosting: Configure and deploy Firebase Hosting sites
 ◯ Storage: Deploy Cloud Storage security rules
 ◯ Emulators: Set up local emulators for Firebase features
 ◯ Remote Config: Get, deploy, and rollback configurations for Remote Config

系統就會為專案初始化必要的 API 和功能。

出現提示時,請初始化即時資料庫。您可以使用資料庫執行個體的預設位置。

? 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

由於您使用的是範例程式碼專案程式碼,請選擇安全性規則的預設檔案,並確保您不會覆寫現有的資料庫規則檔案。

? What file should be used for Realtime Database Security Rules? Database.rules.json

? 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

同樣地,設定函式時,應使用預設檔案,並確保不會覆寫專案範例中現有的 index.jspackage.json 檔案。

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

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

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

? Do you want to install dependencies with npm now? 
Yes

最後,將代管設定設為在專案程式碼中使用 public 目錄,然後使用現有的 index.html 檔案。

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

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

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

部署至 Firebase

請前往 functions 資料夾,然後使用 npm. 安裝所有必要的依附元件

cd functions
npm install

現在您已安裝依附元件並設定專案,可以開始使用首次執行應用程式了。

firebase deploy

以下是您應該會看到的主控台輸出內容:

...

✔ Deploy complete!

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

這個指令會部署網頁應用程式和數個 Cloud Functions for Firebase

在瀏覽器中開啟代管網址 (https://<project-id>.web.app),查看網頁應用程式。您會看到以下介面:

5845443e94705557.png

網頁版使用者介面代表用於查看或修改裝置狀態的第三方平台。如要開始為資料庫填入裝置資訊,請按一下「更新」。這個頁面中不會顯示任何變更,但資料庫的目前狀態將儲存在資料庫中。

您現在可以使用動作控制台將自己部署至 Google 助理的雲端服務建立連結。

設定動作控制台專案

選取「總覽」>「建立動作」,然後選取「新增動作」。輸入要為智慧型住宅意圖提供出貨的 Cloud 函式網址,然後按一下「儲存」

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

9d7b223427f587ca.png

在「開發」>「叫用」分頁中,為動作新增「顯示名稱」,然後按一下「儲存」。這個名稱會顯示在 Google Home 應用程式中。

774d0c40c351c7da.png

a8c4673eb11d76ee.png

如要啟用帳戶連結,請在左側導覽面板中選取「開發」>「帳戶連結」選項。請使用下列帳戶連結設定:

Client-ID

ABC123

用戶端密碼

DEF456

驗證網址

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

權杖網址

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

9730d20b90bcc038.png

按一下 [儲存] 即可儲存帳戶連結設定,然後按一下 [測試] 以為專案啟用測試。

ee0547f05b5efd98.png

系統會將您重新導向至 Simulator。如果找不到「立即啟用測試」,請按一下重設測試 以驗證測試已啟用。

d0495810dbadf059.png

現在您可以開始實作透過裝置與 Google 助理連結狀態所需的 Webhook。

4. 建立洗衣機

動作動作設定完成之後,您就可以新增裝置及傳送資料。您的雲端服務必須處理下列意圖:

  • 當 Google 助理想知道使用者連結的裝置時,就會發生 SYNC 意圖。使用者連結帳戶之後,系統會將這項資訊傳送至您的服務。您應依據所有使用者的裝置及其功能,透過 JSON 酬載回應。
  • 當 Google 助理想知道裝置目前的狀態或狀態時,就會發生 QUERY 意圖。您的 JSON 酬載應會顯示每個要求裝置的狀態。
  • 當 Google 助理代表使用者控制裝置時,就會發生 EXECUTE 意圖。您應使用 JSON 酬載回應每部要求裝置的執行狀態。
  • 當使用者取消連結自己的帳戶與 Google 助理時,就會發生 DISCONNECT 意圖。應停止將這位使用者的裝置事件傳送給 Google 助理。

您將在以下各節中更新先前部署的函式來處理這些意圖。

更新 SYNC 回應

開啟 functions/index.js,其中包含回應 Google 助理要求的代碼。

您必須傳回裝置中繼資料和功能來處理 SYNC 意圖。更新 onSync 陣列中的 JSON,為洗衣機納入裝置資訊和建議的特性

index.js

app.onSync((body) => {
  return {
    requestId: body.requestId,
    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',
        ],
        name: {
          defaultNames: ['My Washer'],
          name: 'Washer',
          nicknames: ['Washer'],
        },
        deviceInfo: {
          manufacturer: 'Acme Co',
          model: 'acme-washer',
          hwVersion: '1.0',
          swVersion: '1.0.1',
        },
        willReportState: true,
        attributes: {
          pausable: true,
        },
      }],
    },
  };
});

部署至 Firebase

使用 Firebase CLI 部署已更新的雲端出貨要求:

firebase deploy --only functions

如要測試智慧型住宅動作,你必須將專案與 Google 帳戶連結。以便透過 Google 助理平台和已登入相同帳戶的 Google Home 應用程式進行測試。

  1. 開啟手機的「Google 助理」設定。請注意,您應該在主控台中使用同一個帳戶登入。
  2. 依序前往 [Google 助理] > [設定] > [居家控制系統] (位於 [Google 助理] 下方)。
  3. 選取右下角的加號 (+) 圖示
  4. 畫面應會顯示測試應用程式,以及 [test] 前置字元和您設定的顯示名稱。
  5. 選取該項目。Google 助理隨即會驗證你的服務並傳送 SYNC 要求,要求你的服務為使用者提供裝置清單。

開啟 Google Home 應用程式,確認你可以看到洗衣機裝置。

ae252220753726f6.png

5. 處理指令和查詢

您的雲端服務現已正確將洗衣機裝置回報給 Google,您需要新增要求裝置狀態及傳送指令的功能。

處理 QUERY 意圖

QUERY 意圖包含一組裝置。請針對每個裝置,回覆目前的狀態。

functions/index.js 中,編輯 QUERY 處理常式以處理意圖要求中包含的目標裝置清單。

index.js

app.onQuery(async (body) => {
  const {requestId} = body;
  const payload = {
    devices: {},
  };
  const queryPromises = [];
  const intent = body.inputs[0];
  for (const device of intent.payload.devices) {
    const deviceId = device.id;
    queryPromises.push(queryDevice(deviceId)
        .then((data) => {
        // Add response to device payload
          payload.devices[deviceId] = data;
        }
        ));
  }
  // Wait for all promises to resolve
  await Promise.all(queryPromises);
  return {
    requestId: requestId,
    payload: payload,
  };
});

針對要求中包含的裝置,傳回儲存在即時資料庫中的目前狀態。更新 queryFirebasequeryDevice 函式,以傳回洗衣機的狀態資料。

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,
  };
};

const queryDevice = async (deviceId) => {
  const data = await queryFirebase(deviceId);
  return {
    on: data.on,
    isPaused: data.isPaused,
    isRunning: data.isRunning,
    currentRunCycle: [{
      currentCycle: 'rinse',
      nextCycle: 'spin',
      lang: 'en',
    }],
    currentTotalRemainingTime: 1212,
    currentCycleRemainingTime: 301,
  };
};

處理 EXECUTE 意圖

EXECUTE 意圖會處理指令以更新裝置狀態。回應會傳回每個指令的狀態 (例如 SUCCESSERRORPENDING),以及新的裝置狀態。

functions/index.js 中,編輯 EXECUTE 處理常式,以處理每個指令所需的屬性清單,以及每個指令的目標裝置組合:

index.js

app.onExecute(async (body) => {
  const {requestId} = body;
  // Execution results are grouped by status
  const result = {
    ids: [],
    status: 'SUCCESS',
    states: {
      online: true,
    },
  };

  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) => {
                  result.ids.push(device.id);
                  Object.assign(result.states, data);
                })
                .catch(() => functions.logger.error('EXECUTE', device.id)));
      }
    }
  }

  await Promise.all(executePromises);
  return {
    requestId: requestId,
    payload: {
      commands: [result],
    },
  };
});

針對每個指令和目標裝置,更新即時資料庫中與要求特徵對應的值。修改 updateDevice 函式以更新適當的 Firebase 參照,並傳回已更新的裝置狀態。

index.js

const updateDevice = async (execution, deviceId) => {
  const {params, command} = execution;
  let state; let 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;
  }

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

6. 測試動作

實作全部三個意圖後,您可以測試動作是否控制了洗衣機。

部署至 Firebase

使用 Firebase CLI 部署已更新的雲端出貨要求:

firebase deploy --only functions

測試洗衣機

現在,你可以在手機上嘗試下列任何語音指令來實現值的變更:

「Ok Google,打開洗衣機。」

「Ok Google,暫停洗衣機。」

「Ok Google,停止洗衣機。」

你也可以提問,查看洗衣機目前的狀態。

「Ok Google,我的洗衣服務了嗎?」

「Ok Google,我的洗衣服務正在運行嗎?」

「Ok Google,洗衣機目前的週期是多少?」

您可以在 Firebase 控制台記錄中查看這些查詢和指令,只要在導覽選單中依序點選「開發」>「函式」>「記錄檔」即可。

ce02fb66fe2037dc.png

7. 向 Google 回報更新問題

您已將雲端服務與智慧型住宅意圖完全整合,可讓使用者控制及查詢裝置目前的狀態。不過,實作方式仍無法讓服務主動將事件資訊 (例如裝置狀態或狀態變更) 傳送給 Google 助理。

使用要求同步功能時,您可以在使用者新增或移除裝置,或是裝置功能改變時觸發新的同步處理要求。透過回報狀態,當使用者實際變更裝置狀態 (例如開啟燈具開關) 或使用其他服務變更狀態時,您的雲端服務會主動將裝置的狀態傳送至住家圖表。

在本節中,您將新增程式碼,從前端網頁應用程式呼叫這些方法。

啟用 HomeGraph API

HomeGraph API 可讓您在裝置的 Home Graph 中儲存及查詢裝置及其狀態。如要使用這個 API,請先開啟 Google Cloud Console,然後啟用 HomeGraph API

在 Google Cloud Console 中,請務必選取與「動作」相符的專案 <project-id>.,然後在 HomeGraph API 的「API Library」畫面中按一下「Enable」(啟用)

ee198858a6eac112.png

啟用報表狀態

寫入即時資料庫會觸發範例專案中的 reportstate 函式。更新 functions/index.js 中的 reportstate 函式,以擷取寫入資料庫的資料,並透過報表狀態發布至主圖。

index.js

exports.reportstate = functions.database.ref('{deviceId}').onWrite(
    async (change, context) => {
      functions.logger.info('Firebase write event triggered Report State');
      const snapshot = change.after.val();

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

      const res = await homegraph.devices.reportStateAndNotification({
        requestBody,
      });
      functions.logger.info('Report state response:', res.status, res.data);
    });

啟用 Request Sync

在前端網路 UI 中重新整理圖示,會觸發範例專案中的 requestsync 函式。在 functions/index.js 中實作 requestsync 函式,以呼叫 HomeGraph API。

index.js

exports.requestsync = functions.https.onRequest(async (request, response) => {
  response.set('Access-Control-Allow-Origin', '*');
  functions.logger.info(`Request SYNC for user ${USER_ID}`);
  try {
    const res = await homegraph.devices.requestSync({
      requestBody: {
        agentUserId: USER_ID,
      },
    });
    functions.logger.info('Request sync response:', res.status, res.data);
    response.json(res.data);
  } catch (err) {
    functions.logger.error(err);
    response.status(500).send(`Error requesting sync: ${err}`);
  }
});

部署至 Firebase

使用 Firebase CLI 部署更新後的程式碼:

firebase deploy --only functions

測試實作成果

按一下網頁 UI 中的「Refresh」(重新整理) 按鈕 ae8d3b25777a5e30.png,然後確認 Firebase 控制台記錄中是否顯示同步處理要求。

5241d663238a8d04.png

接著,在前端網頁 UI 中調整洗衣裝置的屬性,然後按一下「更新」。確認您能在 Firebase 控制台記錄檔中看見向 Google 回報的狀態變更。

8. 恭喜

674c4f4392e98c1.png

恭喜!您已成功使用智慧型住宅動作將 Google 助理與裝置雲端服務整合。

瞭解詳情

歡迎參考以下構想,深入瞭解:

此外,您也可以進一步瞭解如何測試及提交動作以供審查,包括向使用者發布動作的認證程序。