1. 事前準備
物聯網 (IoT) 開發人員可以建構雲端對雲端整合,讓使用者透過 Google Home 應用程式中的觸控控制項,以及 Google 助理的語音指令控制裝置。

瞭解雲端對雲端整合的偵錯工具,是建構 Google 助理正式版整合服務的重要步驟。為方便監控及偵錯,我們提供 Google Cloud Platform (GCP) 指標、記錄和智慧住宅測試套件,協助您找出並解決整合問題。
必要條件
- 請參閱「建立雲端對雲端整合」開發人員指南
- 執行「將智慧住宅裝置連結至 Google 助理」程式碼研究室
建構項目
在本程式碼研究室中,您將部署有 2 個缺陷的雲端對雲端整合,並將其連結至 Google 助理,然後透過智慧住宅測試套件和 Google Cloud Platform (GCP) 指標與記錄檔,偵錯整合的缺陷。
課程內容
- 如何使用 GCP 指標和記錄檔找出並解決實際工作環境問題
- 如何使用智慧住宅測試套件找出功能和 API 問題
軟硬體需求
- 網路瀏覽器,例如 Google Chrome
- 已安裝 Google Home 應用程式的 iOS 或 Android 裝置
- Node.js 10.16 以上版本
- Google Cloud 帳單帳戶
2. 執行有問題的應用程式
取得原始碼
點選下方連結,將本程式碼研究室的範例下載至開發機器:
...或者,您也可以從指令列複製 GitHub 存放區:
$ git clone https://github.com/google-home/smarthome-debug.git
關於專案
洗衣機應用程式包含下列子目錄:
public:前端 UI,可輕鬆控制及監控智慧型洗衣機的狀態。functions:全面實作的雲端服務,可透過 Cloud Functions for Firebase 和 Firebase 即時資料庫管理智慧洗衣機
連結至 Firebase
在開發電腦上開啟終端機,前往 washer-faulty 目錄,然後使用在將智慧住宅裝置連結至 Google 助理程式碼研究室中建立的整合專案,設定 Firebase CLI:
$ cd washer-faulty $ firebase use <firebase-project-id>
部署至 Firebase
前往 functions 資料夾,並使用 npm. 安裝所有必要依附元件。
$ cd functions $ npm install
注意:如果看到下列訊息,請忽略並繼續操作。這項警告是因為部分舊版依附元件所致,詳情請參閱這篇文章。
found 5 high severity vulnerabilities run `npm audit fix` to fix them, or `npm audit` for details
安裝依附元件並設定專案後,即可部署故障洗衣機應用程式。
$ firebase deploy
您應該會看到下列控制台輸出內容:
... ✔ Deploy complete! Project Console: https://console.firebase.google.com/project/<Firebase-project-id>/overview Hosting URL: https://<Firebase-project-id>.firebaseapp.com
更新 HomeGraph
在瀏覽器中開啟主機網址 (https://<firebase-project-id>.firebaseapp.com),即可查看網頁應用程式。在網頁 UI 中,按一下「重新整理」
按鈕,使用「要求同步」,以故障洗衣機應用程式的最新裝置中繼資料更新 HomeGraph。

開啟 Google Home 應用程式,確認是否能看到名為「Faulty Washer」的洗衣機裝置。

3. 測試整合項目
部署專案後,請測試整合服務是否能控制洗衣機。
測試洗衣機
透過手機嘗試下列任一語音指令時,請檢查值是否有所變更:
「Ok Google,開啟洗衣機。」
「Ok Google,啟動洗衣機。」
「Ok Google,暫停洗衣機。」
「Ok Google,繼續洗衣機的行程。」
「Ok Google,停止洗衣機。」
暫停 / 繼續洗衣機時,你會發現 Google 助理會透過語音回應,表示發生錯誤:
「抱歉,我無法連線至『<專案顯示名稱>』。」
如要偵錯這個問題,您首先需要更多錯誤資訊,才能縮小範圍並找出根本原因。
智慧住宅數據分析資訊主頁
如要檢查錯誤,建議前往智慧住宅 Analytics 資訊主頁,當中會匯總雲端服務的使用情況和健康狀態指標圖表:
- 「使用情況」指標會反映雲端對雲端整合的使用趨勢,包括每日活躍使用者人數,以及對完成要求的總請求數。
- 健康狀態指標可協助您監控雲端對雲端整合服務的異常狀況,包括要求延遲時間、成功百分比和錯誤細目。
如要找出錯誤原因,請按照下列步驟存取專案資訊主頁。
- 前往開發人員控制台的「專案」頁面。
- 選取智慧型住宅專案。
- 按一下左選單中的「數據分析」分頁標籤。

- 系統會將您帶往 Google Cloud 專案的資訊主頁清單。選取「Google Home Analytics - Cloud Integration」資訊主頁。

- 向下捲動至「Cloud Fulfillment Errors - Status Breakdown」(雲端出貨錯誤 - 狀態細目) 圖表,即可查看所選時間範圍的錯誤代碼。

PARTNER_RESPONSE_MISSING_DEVICE 錯誤代碼會提供根本原因的提示。接著,根據錯誤代碼擷取事件記錄,以取得更多詳細資料。
存取事件記錄
如要進一步瞭解錯誤,請使用 Cloud Logging 存取 Cloud-to-Cloud 整合的事件記錄。
在 Google Cloud Platform 中開啟「導覽選單」,然後依序選取「作業」>「記錄」>「記錄檔探索工具」,即可存取專案的事件記錄。或者,您可以在搜尋框中搜尋「Logs Explorer」。
在「Search all fields」(搜尋所有欄位) 輸入欄位中輸入查詢 PARTNER_RESPONSE_MISSING_DEVICE,然後按一下「Run Query」(執行查詢)。「Results」(結果) 部分會顯示符合查詢的記錄。

錯誤記錄會顯示智慧住宅事件,並提供錯誤詳細資料,指出:
- 使用者採取的動作是「繼續洗衣」(
actionType:「STARTSTOP_UNPAUSE」),對應於最近失敗的語音指令。 - 相關聯的偵錯訊息為「
JSON response does not include device.」
根據偵錯訊息,您應檢查洗衣機應用程式為何未在 EXECUTE 回應中加入正確裝置。
找出錯誤的根本原因
在 functions/index.js 中,找出會傳回每個指令狀態和新裝置狀態的 EXECUTE 處理常式 (位於 onExecute 陣列中)。裝置 ID 是否會插入 EXECUTE 回應,取決於 updateDevice 函式的解析結果:
index.js
app.onExecute(async (body) => {
...
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((e) =>
functions.logger.error('EXECUTE',
device.id, e.message)));
}
}
}
進一步檢查 updateDevice 函式如何處理洗衣機的暫停 / 繼續操作,您會發現要比對的暫停 / 繼續指令字串有誤:
index.js
const updateDevice = async (execution, deviceId) => {
const {params, command} = execution;
let state; let ref;
switch (command) {
...
case 'action.devices.commands.PauseUnpausePause':
const data = await queryDevice(deviceId);
state = (data.isPaused === false && data.isRunning === false)
? {isRunning: false, isPaused: false}
: {isRunning: !params.pause, isPaused: params.pause};
ref = getFirebaseRef().child(deviceId).child('StartStop');
break;
}
return ref.update(state)
.then(() => state);
};
修正錯誤
現在您已找出錯誤的根本原因,可以修正暫停 / 繼續指令的字串:
index.js
const updateDevice = async (execution, deviceId) => {
const {params, command} = execution;
let state; let ref;
switch (command) {
...
case 'action.devices.commands.PauseUnpause':
const data = await queryDevice(deviceId);
state = (data.isPaused === false && data.isRunning === false)
? {isRunning: false, isPaused: false}
: {isRunning: !params.pause, isPaused: params.pause};
ref = getFirebaseRef().child(deviceId).child('StartStop');
break;
}
return ref.update(state)
.then(() => state);
};
測試修正結果
使用 Firebase CLI 部署更新後的程式碼:
firebase deploy --only functions
請重試下列語音指令,你會發現 Google 助理現在會在暫停 / 繼續洗衣機時正確回應。
「Ok Google,暫停洗衣機。」
=>
「好的,正在暫停洗衣機。」
「Ok Google,繼續洗衣機的行程。」
=>
「好的,洗衣機將繼續運作。」
你也可以提出問題,測試洗衣機的目前狀態。
「Ok Google,洗衣機開著嗎?」
「Ok Google,洗衣機正在運作嗎?」
「Ok Google,洗衣機目前處於哪個行程?」
4. 使用測試套件測試整合項目
除了手動測試,您也可以使用自動化智慧住宅測試套件,根據與整合項目相關聯的裝置類型和特徵,驗證使用案例。測試套件會執行一系列測試,偵測整合中的問題,並針對失敗的測試案例顯示資訊豐富的訊息,方便您在深入研究事件記錄檔前加快偵錯速度。
執行智慧型住宅測試套件
請按照下列操作說明,透過測試套件測試雲端對雲端整合:
- 在網路瀏覽器中開啟智慧住宅測試套件。
- 按一下右上角的按鈕登入 Google。這樣一來,測試套件就能直接將指令傳送至 Google 助理。
- 在「專案 ID」欄位中,輸入雲端對雲端整合的專案 ID。然後點選「下一步」繼續。
- 在「測試設定」步驟中,測試套件會列出洗衣機的裝置類型和特徵。

- 由於範例洗衣機應用程式沒有新增 / 移除 / 重新命名洗衣機的 UI,請停用「測試要求同步」選項。在實際運作系統中,每當使用者新增 / 移除 / 重新命名裝置時,您都必須觸發「要求同步」。
- 按一下「下一步」即可開始執行測試。
測試套件執行完成後,即可查看測試案例的結果。您會發現兩個測試案例失敗,並顯示各自的錯誤訊息:

如要偵錯雲端對雲端整合的失敗問題,請先分析錯誤訊息,找出錯誤的根本原因。
分析錯誤訊息
為協助開發人員找出根本原因,測試套件會針對每個失敗的測試案例顯示錯誤訊息,指出失敗原因。
以上述第一個失敗的測試案例為例,

錯誤訊息指出測試套件預期在從雲端對雲端整合回報的狀態中找到 "isPause": true,但實際狀態只包含 "isPause": false。
此外,第二個測試案例失敗的錯誤訊息指出,Cloud-to-Cloud 整合的 QUERY 回應中的狀態包含 "isPause": true,這與 Cloud-to-Cloud 整合回報的狀態 "isPause": false 不同:

根據這兩則錯誤訊息,您應檢查整合報告是否isPaused顯示正確值。
找出錯誤的根本原因
開啟 functions/index.js,其中包含 reportstate 函式,可使用「回報狀態」將狀態變更發布至住家圖表。檢查 Report State 酬載,您會發現酬載缺少 isPaused 狀態,這正是測試套件在失敗的測試案例中檢查的項目。
index.js
exports.reportstate = functions.database.ref('{deviceId}').onWrite(
async (change, context) => {
...
const requestBody = {
requestId: 'ff36a3cc', /* Any unique ID */
agentUserId: USER_ID,
payload: {
devices: {
states: {
/* Report the current state of our washer */
[context.params.deviceId]: {
online: snapshot.online,
on: snapshot.OnOff.on,
isRunning: snapshot.StartStop.isRunning,
currentRunCycle: [{
currentCycle: 'rinse',
nextCycle: 'spin',
lang: 'en',
}],
currentTotalRemainingTime: 1212,
currentCycleRemainingTime: 301,
},
},
},
},
};
const res = await homegraph.devices.reportStateAndNotification({
requestBody,
});
...
});
修正錯誤
現在您已找出錯誤的根本原因,請在「Report State」酬載中新增 isPaused 狀態,藉此修訂 functions/index.js:
index.js
exports.reportstate = functions.database.ref('{deviceId}').onWrite(
async (change, context) => {
...
const requestBody = {
requestId: 'ff36a3cc', /* Any unique ID */
agentUserId: USER_ID,
payload: {
devices: {
states: {
/* Report the current state of our washer */
[context.params.deviceId]: {
online: snapshot.online,
on: snapshot.OnOff.on,
isPaused: snapshot.StartStop.isPaused,
isRunning: snapshot.StartStop.isRunning,
currentRunCycle: [{
currentCycle: 'rinse',
nextCycle: 'spin',
lang: 'en',
}],
currentTotalRemainingTime: 1212,
currentCycleRemainingTime: 301,
},
},
},
},
};
...
});
測試修正結果
使用 Firebase CLI 部署更新後的程式碼:
$ firebase deploy --only functions
重新執行智慧型住宅測試套件,您會發現所有測試案例都已通過。

5. 恭喜

恭喜!您已成功學會如何使用智慧住宅測試套件、GCP 指標和記錄檔,排解雲端對雲端整合問題。
瞭解詳情
完成本程式碼研究室後,請嘗試下列練習並探索其他資源:
- 在裝置中新增更多支援的特徵,並使用測試套件進行測試。
- 建立資訊主頁、設定快訊,以及以程式輔助方式存取指標資料,取得整合的實用用量指標。
- 探索智慧型住宅的本機執行要求。
- 如要瞭解詳情,請參閱 GitHub 範例。
您也可以進一步瞭解如何測試及提交整合功能以供審查,包括將整合功能發布給使用者的認證程序。