智能家居 Action 的通知

通过通知,您的 smart home Action 可以使用 Google Assistant 向用户传达与设备相关的重要事件或变化。您可以实现通知来及时提醒用户设备事件(例如有人在门口时),或报告所请求设备的状态变化(例如门锁舌成功锁定到位或被卡住)。

您的 smart home Action 可以向用户发送以下类型的通知:

  • 主动通知:在事先没有用户对设备发出任何请求的情况下,向用户提醒 smart home 设备事件,例如按门铃。

  • 后续响应:设备命令请求成功或失败的确认,例如在锁门时。请为需要时间才能完成的设备命令使用这些提醒。只有从智能音箱和智能显示屏发送设备命令请求时,才支持后续响应。

Assistant 会在智能音箱和智能显示屏上以公告的形式向用户提供这些通知。主动通知默认处于关闭状态。 用户可以从 Google Home app (GHA) 开启或关闭所有主动通知。

会触发通知的事件

当发生设备事件时,您的 Action 执行方式会向 Google 发送通知请求。您的 smart home Action 支持的设备特征决定了可用的通知事件类型,以及您可以在这些通知中包含的数据。

以下特征支持主动通知:

特征 事件
ObjectDetection 设备检测到的对象,比如在门口检测到熟悉的面孔。例如:“小红和小波在前门门口。”
RunCycle 设备完成一个周期。例如:“洗衣机洗衣程序已结束。”
SensorState 设备检测到受支持的传感器状态。例如:“烟雾检测器检测到烟雾。”
TemperatureControl 设备达到了设定温度。例如:“烤箱已经预热到 350 度。”
ArmDisarm 开门的动作会触发系统进入预警状态,并显示进门倒计时。
CameraStream 设备检测到物体或动作后摄像头直播内容的链接。
MotionDetection “2020 年 7 月 1 日中午 12 点检测到动作。”

以下特征支持后续响应:

特征 事件
ArmDisarm 执行 action.devices.commands.ArmDisarm 设备命令后的完成状态和状态变更。例如:“安防系统已开启。”
LockUnlock 执行 action.devices.commands.LockUnlock 设备命令后的完成状态和状态变更。例如:“前门已被上锁”或“前门卡住了”。
NetworkControl 执行 action.devices.commands.TestNetworkSpeed 设备命令后的完成状态和状态变更。例如:“你的网速测试已完成。办公室路由器的下载速度目前为 80.2 Kbps,上传速度为 9.3 Kbps。”
OpenClose 执行 action.devices.commands.OpenClose 设备命令后的完成状态和状态变更。例如:“前门已打开”或“前门无法打开”。
StartStop 执行 action.devices.commands.StartStop 设备命令后的完成状态和状态变更。例如:“吸尘器已启动。”

所有设备类型都支持针对适用特征的通知。

为智能家居 Action 构建通知

请在以下阶段为 smart home Action 添加通知:

  1. 向 Google 指示您的 smart home 设备应用中是否启用了通知。如果用户在您的应用中开启或关闭通知,则发送 SYNC 请求来告知 Google 设备发生的变化。
  2. 当相关设备事件或状态更改发生并触发通知时,通过调用 Report State reportStateAndNotification API 发送通知请求。如果设备状态发生变化,您可以在 Report State 和通知调用中同时发送状态和通知载荷。

以下部分更详细地介绍了这些步骤。

指示你的应用是否启用了通知

用户可以通过在 GHA 中启用此功能来选择是否要接收主动通知。在 smart home 设备的应用中,您还可以根据需要添加可让用户从设备上明确切换通知的功能,例如从应用设置切换。

通过进行请求同步调用来更新设备数据,向 Google 指示已为你的设备启用通知。每当用户在你的应用中更改此设置时,你都应发送 SYNC 请求。

SYNC 响应中,发送以下某个更新:

  • 如果用户在你的设备应用中明确开启了通知,或者如果你未提供开关切换选项,请将 devices.notificationSupportedByAgent 属性设置为 true
  • 如果用户在你的设备应用中明确关闭了通知,请将 devices.notificationSupportedByAgent 属性设置为 false

以下代码段举例说明了如何设置 SYNC 响应:

devices: [{
   id: 'device123',
   ...
   notificationSupportedByAgent: true,
}]

向 Google 发送通知请求

如需在 Assistant 上触发通知,您的执行方式需要通过 Report State 和 Notification API 调用将通知载荷发送到 Google Home Graph

启用 Google HomeGraph API

  1. Google Cloud Console 中,转到 HomeGraph API 页面。

    转到 HomeGraph API 页面
  2. 选择与您的 smart home 项目 ID 匹配的项目。
  3. 点击启用

创建服务账号密钥

按照以下说明从 Google Cloud Console 生成服务帐号密钥:

注意:请确保你在执行以下步骤时使用的 GCP 项目正确无误。即与您的 smart home 项目 ID 匹配的项目。
  1. Google Cloud Console 中,转到创建服务帐号密钥页面。

    转到“创建服务账号密钥”页面
  2. 服务账号列表中,选择创建服务账号
  3. 服务账号名称字段中,输入一个名称。
  4. 服务账号 ID 字段中,输入一个 ID。
  5. 角色列表中,依次选择 Service Accounts > Service Account Token Creator

  6. 对于密钥类型,选择 JSON 选项。

  7. 点击创建。包含密钥的 JSON 文件就会下载到计算机。

发送通知

使用 devices.reportStateAndNotification API 发出通知请求调用。你的 JSON 请求必须包含 eventId,即你的平台为触发通知的事件生成的唯一 ID。eventId 应是一个随机 ID,每次你发送通知请求时,该 ID 都是不同的。

在你在 API 调用中传递的 notifications 对象中,添加 priority 值来定义应如何显示通知。您的 notifications 对象可能包含不同的字段,具体取决于设备特征。

按照以下某个路径设置载荷并调用该 API:

发送主动通知载荷

如需调用该 API,请从以下某个标签页中选择一个选项:

HTTP

Home Graph API 提供 HTTP 端点

  1. 使用下载的服务账号 JSON 文件创建 JSON 网络令牌 (JWT)。如需了解详情,请参阅使用服务账号进行身份验证
  2. 使用 oauth2l 获取具有 https://www.googleapis.com/auth/homegraph 范围的 OAuth 2.0 访问令牌:
  3. oauth2l fetch --credentials service-account.json \
      --scope https://www.googleapis.com/auth/homegraph
    
  4. 使用 agentUserId 创建 JSON 请求。 以下是 Report State 和通知的 JSON 请求示例:
  5. {
      "agentUserId": "PLACEHOLDER-USER-ID",
      "eventId": "PLACEHOLDER-EVENT-ID",
      "requestId": "PLACEHOLDER-REQUEST-ID",
      "payload": {
        "devices": {
          "notifications": {
            "PLACEHOLDER-DEVICE-ID": {
              "ObjectDetection": {
                "priority": 0,
                "detectionTimestamp": 1534875126750,
                "objects": {
                  "named": [
                    "Alice"
                  ],
                  "unclassified": 2
                }
              }
            }
          }
        }
      }
    }
    
  6. Report State 和通知 JSON 与向 Google Home Graph 端点的 HTTP POST 请求中的令牌合并。作为测试,以下示例演示了如何在命令行中使用 curl 发出请求:
  7. curl -X POST -H "Authorization: Bearer ACCESS_TOKEN" \
      -H "Content-Type: application/json" \
      -d @request-body.json \
      "https://homegraph.googleapis.com/v1/devices:reportStateAndNotification"
    

gRPC

Home Graph API 提供 gRPC 端点

  1. 获取 Home Graph API 的协议缓冲区服务定义
  2. 按照 gRPC 开发者文档进行操作,为其中一种受支持的语言生成客户端存根。
  3. 调用 ReportStateAndNotification 方法。

Node.js

Google API Node.js 客户端Home Graph API 提供绑定。

  1. 使用应用默认凭据初始化 google.homegraph 服务。
  2. 使用 ReportStateAndNotificationRequest 调用 reportStateAndNotification 方法。它会返回一个包含 ReportStateAndNotificationResponsePromise
const homegraphClient = homegraph({
  version: 'v1',
  auth: new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/homegraph'
  })
});

const res = await homegraphClient.devices.reportStateAndNotification({
  requestBody: {
    agentUserId: 'PLACEHOLDER-USER-ID',
    eventId: 'PLACEHOLDER-EVENT-ID',
    requestId: 'PLACEHOLDER-REQUEST-ID',
    payload: {
      devices: {
        notifications: {
          'PLACEHOLDER-DEVICE-ID': {
            ObjectDetection: {
              priority: 0,
              detectionTimestamp: 1534875126750,
              objects: {
                named: ['Alice'],
                unclassified: 2
              }
            }
          }
        }
      }
    }
  }
});
    

Java

适用于 Java 的 HomeGraph API 客户端库Home Graph API 提供绑定。

  1. 使用应用默认凭据初始化 HomeGraphApiService
  2. 使用 ReportStateAndNotificationRequest 调用 reportStateAndNotification 方法。它会返回一个 ReportStateAndNotificationResponse
// Get Application Default credentials.
GoogleCredentials credentials =
    GoogleCredentials.getApplicationDefault()
        .createScoped(List.of("https://www.googleapis.com/auth/homegraph"));

// Create Home Graph service client.
HomeGraphService homegraphService =
    new HomeGraphService.Builder(
            GoogleNetHttpTransport.newTrustedTransport(),
            GsonFactory.getDefaultInstance(),
            new HttpCredentialsAdapter(credentials))
        .setApplicationName("HomeGraphExample/1.0")
        .build();

// Build device notification payload.
Map<?, ?> notifications =
    Map.of(
        "ObjectDetection",
        Map.of(
            "priority", 0,
            "detectionTimestamp", 1534875126,
            "objects", Map.of("named", List.of("Alice"), "unclassifed", 2)));

// Send notification.
ReportStateAndNotificationRequest request =
    new ReportStateAndNotificationRequest()
        .setRequestId("PLACEHOLDER-REQUEST-ID")
        .setAgentUserId("PLACEHOLDER-USER-ID")
        .setEventId("PLACEHOLDER-EVENT-ID")
        .setPayload(
            new StateAndNotificationPayload()
                .setDevices(
                    new ReportStateAndNotificationDevice()
                        .setNotifications(Map.of("PLACEHOLDER-DEVICE-ID", notifications))));
homegraphService.devices().reportStateAndNotification(request);
    
发送后续响应载荷

后续响应的载荷包含请求的状态、事件失败的错误代码(如果适用),以及在 EXECUTE intent 请求期间提供的有效 followUpToken。必须在五分钟内使用 followUpToken,才能保持有效状态并将响应与原始请求正确关联。

以下代码段说明了一个带有 followUpToken 字段的 EXECUTE 请求载荷示例。

{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [{
    "intent": "action.devices.EXECUTE",
    "payload": {
      "commands": [{
        "devices": [{
          "id": "123",
        }],
        "execution": [{
          "command": "action.devices.commands.TestNetworkSpeed",
          "params": {
            "testDownloadSpeed": true,
            "testUploadSpeed": false,
            "followUpToken": "PLACEHOLDER"
          }
        }]
      }]
    }
  }]
};

Google 使用 followUpToken 仅在用户最初与之互动的设备上输出通知,而不会在用户的所有设备上广播。

如需调用该 API,请从以下某个标签页中选择一个选项:

HTTP

Home Graph API 提供 HTTP 端点

  1. 使用下载的服务账号 JSON 文件创建 JSON 网络令牌 (JWT)。如需了解详情,请参阅使用服务账号进行身份验证
  2. 使用 oauth2l 获取具有 https://www.googleapis.com/auth/homegraph 范围的 OAuth 2.0 访问令牌:
  3. oauth2l fetch --credentials service-account.json \
      --scope https://www.googleapis.com/auth/homegraph
    
  4. 使用 agentUserId 创建 JSON 请求。 以下是 Report State 和通知的 JSON 请求示例:
  5. {
      "agentUserId": "PLACEHOLDER-USER-ID",
      "eventId": "PLACEHOLDER-EVENT-ID",
      "requestId": "PLACEHOLDER-REQUEST-ID",
      "payload": {
        "devices": {
          "notifications": {
            "PLACEHOLDER-DEVICE-ID": {
              "NetworkControl": {
                "priority": 0,
                "followUpResponse": {
                  "status": "SUCCESS",
                  "followUpToken": "PLACEHOLDER",
                  "networkDownloadSpeedMbps": 23.3,
                  "networkUploadSpeedMbps": 10.2
                }
              }
            }
          }
        }
      }
    }
    
  6. Report State 和通知 JSON 与向 Google Home Graph 端点的 HTTP POST 请求中的令牌合并。作为测试,以下示例演示了如何在命令行中使用 curl 发出请求:
  7. curl -X POST -H "Authorization: Bearer ACCESS_TOKEN" \
      -H "Content-Type: application/json" \
      -d @request-body.json \
      "https://homegraph.googleapis.com/v1/devices:reportStateAndNotification"
    

gRPC

Home Graph API 提供 gRPC 端点

  1. 获取 Home Graph API 的协议缓冲区服务定义
  2. 按照 gRPC 开发者文档进行操作,为其中一种受支持的语言生成客户端存根。
  3. 调用 ReportStateAndNotification 方法。

Node.js

Google API Node.js 客户端Home Graph API 提供绑定。

  1. 使用应用默认凭据初始化 google.homegraph 服务。
  2. 使用 ReportStateAndNotificationRequest 调用 reportStateAndNotification 方法。它会返回一个包含 ReportStateAndNotificationResponsePromise
const followUpToken = executionRequest.inputs[0].payload.commands[0].execution[0].params.followUpToken;

const homegraphClient = homegraph({
  version: 'v1',
  auth: new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/homegraph'
  })
});

const res = await homegraphClient.devices.reportStateAndNotification({
  requestBody: {
    agentUserId: 'PLACEHOLDER-USER-ID',
    eventId: 'PLACEHOLDER-EVENT-ID',
    requestId: 'PLACEHOLDER-REQUEST-ID',
    payload: {
      devices: {
        notifications: {
          'PLACEHOLDER-DEVICE-ID': {
            NetworkControl: {
              priority: 0,
              followUpResponse: {
                status: 'SUCCESS',
                followUpToken,
                networkDownloadSpeedMbps: 23.3,
                networkUploadSpeedMbps: 10.2,
              }
            }
          }
        }
      }
    }
  }
});
    

Java

适用于 Java 的 HomeGraph API 客户端库Home Graph API 提供绑定。

  1. 使用应用默认凭据初始化 HomeGraphApiService
  2. 使用 ReportStateAndNotificationRequest 调用 reportStateAndNotification 方法。它会返回一个 ReportStateAndNotificationResponse
// Get Application Default credentials.
GoogleCredentials credentials =
    GoogleCredentials.getApplicationDefault()
        .createScoped(List.of("https://www.googleapis.com/auth/homegraph"));

// Create Home Graph service client.
HomeGraphService homegraphService =
    new HomeGraphService.Builder(
            GoogleNetHttpTransport.newTrustedTransport(),
            GsonFactory.getDefaultInstance(),
            new HttpCredentialsAdapter(credentials))
        .setApplicationName("HomeGraphExample/1.0")
        .build();

// Extract follow-up token.
ExecuteRequest.Inputs executeInputs = (Inputs) executeRequest.getInputs()[0];
String followUpToken =
    (String)
        executeInputs
            .getPayload()
            .getCommands()[0]
            .getExecution()[0]
            .getParams()
            .get("followUpToken");

// Build device follow-up response payload.
Map<?, ?> followUpResponse =
    Map.of(
        "NetworkControl",
        Map.of(
            "priority",
            0,
            "followUpResponse",
            Map.of(
                "status",
                "SUCCESS",
                "followUpToken",
                followUpToken,
                "networkDownloadSpeedMbps",
                23.3,
                "networkUploadSpeedMbps",
                10.2)));

// Send follow-up response.
ReportStateAndNotificationRequest request =
    new ReportStateAndNotificationRequest()
        .setRequestId("PLACEHOLDER-REQUEST-ID")
        .setAgentUserId("PLACEHOLDER-USER-ID")
        .setEventId("PLACEHOLDER-EVENT-ID")
        .setPayload(
            new StateAndNotificationPayload()
                .setDevices(
                    new ReportStateAndNotificationDevice()
                        .setNotifications(Map.of("PLACEHOLDER-DEVICE-ID", followUpResponse))));
homegraphService.devices().reportStateAndNotification(request);
    

日志记录

使用 Cloud Logging 访问事件日志中所述,通知支持事件日志记录。这些日志有助于你在 Action 中测试和维护通知质量。

以下是 notificationLog 条目的架构:

媒体资源 说明
requestId 通知请求 ID。
structName 通知结构体的名称,例如“ObjectDetection”。
status 指示通知的状态

status 字段包含可指示通知载荷中错误的各种状态。部分功能可能仅适用于尚未发布正式版的 Action。

状态示例包括:

状态 说明
EVENT_ID_MISSING 表示缺少必要的 eventId 字段。
PRIORITY_MISSING 表示缺少 priority 字段。
NOTIFICATION_SUPPORTED_BY_AGENT_FALSE 表示 SYNC 中提供的通知设备的 notificationSupportedByAgent 属性为 false。
NOTIFICATION_ENABLED_BY_USER_FALSE 表示用户未在 GHA 中的通知设备上启用通知。此状态仅适用于尚未发布正式版的 Action。
NOTIFYING_DEVICE_NOT_IN_STRUCTURE 表示用户没有将通知设备分配给住宅/结构。此状态仅适用于尚未发布正式版的 Action。

除了这些适用于所有通知的常规状态外,在适用的情况下,status 字段还可能包含特征特有的状态(例如 OBJECT_DETECTION_DETECTION_TIMESTAMP_MISSING)。