智能家居 Action 的通知

借助通知,您的 smart home Action 可以使用 Google Assistant 与用户就设备相关的重要事件或变更进行沟通。您可以实现通知,以及时提醒用户设备事件(例如有人在门口时),或报告所请求的设备状态变化(例如门锁已成功接住或卡住)。

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

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

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

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

会触发通知的事件

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

以下特征支持主动通知:

特征 活动
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 操作添加通知:

  1. 通过您的 smart home 设备应用向 Google 指明是否已启用通知。如果用户在您的应用中开启或关闭通知,请发送 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 和 Notification 的 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 和 Notification 的 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)。