1. 准备工作
作为物联网 (IoT) 开发者,你可以构建智能家居 Action,让用户能够通过 Google Home 应用中的触控和 Google 助理语音指令控制自己的设备。
了解智能家居 Action 的调试工具,是打造与 Google 助理的生产质量集成的重要步骤。为方便监控和调试,我们提供了 Google Cloud Platform (GCP) 指标、Logging 和智能家居测试套件,可帮助你识别和解决与 Action 相关的问题。
前提条件
- 阅读创建智能家居 Action 开发者指南
- 运行将智能家居设备关联到 Google 助理 Codelab
构建内容
在此 Codelab 中,你将部署一个智能家居 Action 有 2 个缺陷,并将其连接到 Google 助理,然后通过测试套件对 Action 的缺陷进行调试,以便测试智能家居和 Google Cloud Platform (GCP) 指标和日志记录。
学习内容
- 如何使用 GCP 指标和日志记录找出并解决生产环境中的问题
- 如何使用适用于智能家居的测试套件来识别功能和 API 问题
所需条件
- 网络浏览器,例如 Google Chrome
- 安装了 Google Home 应用的 iOS 或 Android 设备
- Node.js 10.16 或更高版本
- Google Cloud 结算帐号
2. 运行故障应用
获取源代码
点击以下链接,将此 Codelab 的示例下载到您的开发机器上:
...或者,您也可以通过命令行克隆 GitHub 代码库:
$ git clone https://github.com/googlecodelabs/smarthome-debug.git
项目简介
洗衣机应用包含以下子目录:
public
:轻松控制和监控智能洗衣机状态的前端界面。functions
:一种完全实现的云服务,可使用 Cloud Functions for Firebase 和 Firebase Realtime Database 管理智能洗衣机。
关联到 Firebase
在开发机器上打开终端。前往 washer-faulty
目录,然后根据将智能家居设备连接到 Google 助理 Codelab,设置 Firebase CLI 项目:
$ cd washer-faulty $ firebase use <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/<project-id>/overview Hosting URL: https://<project-id>.firebaseapp.com
更新 HomeGraph
在浏览器中打开 Hosting 网址 (https://<project-id>.firebaseapp.com
) 以查看 Web 应用。在网页界面上,点击刷新 按钮,通过请求同步功能更新 HomeGraph,使其包含来自洗衣机应用的最新设备元数据:
打开 Google Home 应用,验证你能否看到名为 Faulty Washer 的洗衣机设备。
3. 测试您的 Action
部署项目后,请测试 Action 是否控制洗衣机。
测试洗衣机
当您尝试通过手机执行以下任一语音指令时,请检查值是否发生更改:
“Ok Google,启动洗衣机。”
“Ok Google,运行洗衣机。”
“Ok Google,暂停洗衣机。”
“Ok Google,恢复洗衣机。”
“Ok Google,让洗衣机停止运行。”
当你暂停 / 恢复洗衣机时,你会注意到 Google 助理通过语音回答了一些问题:
“抱歉,我无法访问<project display name>。”
要调试此问题,您首先需要了解有关此错误的更多信息以缩小范围并确定根本原因。
智能家居 Analytics 信息中心
建议查看 Smarthome Analytics 信息中心,该信息中心汇总了云执行方式的使用情况和健康状况指标图表:
- 用量指标反映了你的智能家居 Action 的使用趋势,包括每日活跃用户数和执行方式请求总数。
- 运行状况指标可帮助您监控智能家居 Action 的异常情况,包括请求延迟时间、成功百分比和错误细分。
要缩小错误原因,请按照以下步骤访问项目信息中心。
- 在 Actions 控制台中,转到“Projects”页面。
- 选择你的智能家居项目。
- 选择 Analytics 标签页,然后点击 Go to Google Cloud Platform。
- 系统会将您转到 Google Cloud 上的项目信息中心列表。选择 Google Home Analytics - Cloud Integration 信息中心。
- 向下滚动到 Cloud Fulfillment 错误 - 状态细分图表,查看突出显示的时间范围的错误代码。
PARTNER_RESPONSE_MISSING_DEVICE
错误代码可提示根本原因。接下来,根据错误代码检索事件日志,以获取更多详细信息。
访问事件日志
如需更详细地了解此错误,请通过 Cloud Logging 访问智能家居 Action 的事件日志。
打开 Google Cloud Platform 中的导航菜单,然后在操作下选择 Logging > 日志浏览器以访问项目的事件日志。您也可以在搜索框中搜索日志浏览器。
在查询部分,输入查询 PARTNER_RESPONSE_MISSING_DEVICE
,然后点击运行查询。与查询匹配的日志会显示在查询结果部分中。
错误日志会显示智能家居事件,错误详情指明了:
- 用户执行的操作是“恢复洗衣机”(
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':
state = {isPaused: params.pause};
if (params.pause) state.isRunning = false;
ref = firebaseRef.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':
state = {isPaused: params.pause};
if (params.pause) state.isRunning = false;
ref = firebaseRef.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. 使用测试套件测试您的 Action
除了手动测试之外,你还可以根据自动化 Action 的测试套件,根据与 Action 关联的设备类型和特征来验证用例。测试套件会运行一系列测试来检测 Action 中的问题,并显示失败测试用例的信息性消息,在调试事件日志之前加快调试速度。
运行智能家居测试套件
请按照以下说明测试智能家居 Action by Test Suite:
- 在网络浏览器中,打开智能家居测试套件。
- 使用右上角的按钮登录 Google。这样,测试套件便可以直接将命令发送给 Google 助理。
- 在 Project ID 字段中,输入智能家居 Action 的项目 ID。然后,点击下一步以继续操作。
- 在测试设置步骤中,您会看到测试套件,其中列出了洗衣机的设备类型和特征。
- 停用测试请求同步选项,因为示例洗衣机应用没有添加 / 移除 / 重命名洗衣机的界面。在生产系统中,每当用户添加/移除/重命名设备时,都必须触发请求同步。
- 点击下一步以开始运行测试。
测试套件运行完毕后,查看测试用例的结果。您会发现有两个失败的测试用例,并各自带有错误消息:
要调试智能家居 Action 中的故障,你需要先分析错误消息,找出错误的根本原因。
分析错误消息
为了帮助开发者确定根本原因,测试套件会显示每个失败的测试用例的错误消息,指出失败的原因。
对于上述第一个失败的测试用例,
其错误消息表明,在智能家居 Action 报告的状态下,测试套件需要 "isPause": true
,但实际状态仅包含 "isPause": false
。
此外,第二个失败测试用例的错误消息指出,智能家居 Action 的 QUERY
响应中的状态包括 "isPause": true
,这与智能家居 Action 报告的状态中的 "isPause": false
不同:
然后,根据上述两条错误消息,你应该检查你的 Action 是否报告了包含正确值的 isPaused
。
确定错误的根本原因
打开 functions/index.js
,其中包含 reportstate
函数,该函数通过报告状态将状态更改发布到 Home Graph。检查报告状态载荷,您会发现该载荷缺少 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: true,
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,
});
...
});
修正错误
现在,您已经确定了错误的根本原因,接下来可以通过向报告状态载荷中添加 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: true,
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. 恭喜
恭喜!你已成功学会如何通过测试套件对智能家居 Action 以及 GCP 指标和日志记录进行问题排查。
了解详情
在此 Codelab 的基础上,尝试做以下练习并浏览其他资源:
- 向您的设备添加更多受支持的特征,并通过测试套件对其进行测试。
- 你可以创建信息中心、设置提醒以及以编程方式访问指标数据,以便获取有关 Action 的实用使用情况指标。
- 探索智能家居的本地执行方式。
- 查看我们的 GitHub 示例以了解更多信息。
您还可以详细了解如何测试和提交 Action 以供审核,包括向用户发布 Action 的认证流程。