AWS IoT
开发人员指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 Amazon AWS 入门

设备和任务

设备与 Jobs 的通信使用 MQTT 协议使用 HTTP SigV4使用 HTTP TLS
设备与 Jobs 的通信

设备可通过以下三种方法之一与 Jobs 进行通信:

  • MQTT

  • HTTP SigV4

  • HTTP TLS

使用 MQTT 协议

Jobs 服务和设备之间的通信可通过 MQTT 协议进行。设备将订阅 MQTT 主题,以便获得新任务通知和接收来自 Jobs 服务的响应。设备在 MQTT 主题上发布以查询或更新任务执行的状态。每台设备都有自己的一般 MQTT 主题。有关发布和订阅 MQTT 主题的更多信息,请参阅AWS IoT 的消息代理

注意

您在通过 MQTT 与 Jobs 进行通信时必须使用正确的终端节点。要查找该终端节点,请使用 DescribeEndpoint 命令。例如,使用以下 CLI:

aws iot describe-endpoint --endpoint-type iot:Data

您将获得一个类似于下面的结果:

{ "endpointAddress": "a1b2c3d4e5f6g7.iot.us-west-2.amazonaws.com" }

利用此方法,您的设备可使用其特定于设备的证书和私有密钥对 Jobs 服务进行身份验证。

设备可以:

  • 在某个设备的待处理任务执行列表中添加或删除任务执行时收到通知,方式是通过订阅 $aws/things/thing-name/jobs/notify MQTT 主题,其中 thing-name 是与设备关联的事物的名称。

  • 在下一个待处理任务执行发生更改时收到通知,方式是通过订阅 $aws/things/thing-name/jobs/notify-next MQTT 主题,其中 thing-name 是与设备关联的事物的名称。

  • 通过调用 UpdateJobExecution API 来更新任务执行的状态。

  • 通过调用 DescribeJobExecution API 来查询任务执行的状态。

  • 通过调用 GetPendingJobExecutions API 来检索待处理任务执行的列表。

  • 通过使用 jobId $next 调用 DescribeJobExecution API 来检索下一个待处理任务执行。

  • 通过调用 StartNextPendingJobExecution API 来获取和开始下一个待处理任务执行。

Jobs 服务通过将 acceptedrejected 追加到用于发出请求的主题,在 MQTT 主题上发布成功和失败消息。例如,如果在 $aws/things/myThing/jobs/get 主题上发布请求消息,则 Jobs 服务将在 $aws/things/myThing/jobs/get/accepted 主题上发布成功消息,并在 $aws/things/myThing/jobs/get/rejected 主题上发布已拒绝消息。

使用 HTTP SigV4

Jobs 服务和设备之间的通信可通过端口 443 上的 HTTP SigV4 进行。这是由 AWS 开发工具包和 CLI 使用的方法。有关这些工具的更多信息,请参阅 AWS CLI 命令参考:iot-jobs-dataAWS 开发工具包和工具并参考您的首选语言的 IotJobsDataPlane 部分。

注意

在通过 HTTP SigV4 或者使用 AWS 开发工具包或 CLI IotJobsDataPlane 命令与 Jobs 进行通信时,您必须使用正确的终端节点。要查找该终端节点,请使用 DescribeEndpoint 命令。例如,使用以下 CLI:

aws iot describe-endpoint --endpoint-type iot:Jobs

您将获得一个类似于下面的结果:

{ "endpointAddress": "a1b2c3d4e5f6g7.jobs.iot.us-west-2.amazonaws.com" }

利用这种通信方法,您的设备将使用 IAM 凭证对 Jobs 服务进行身份验证。

可以使用此方法执行以下命令:

  • DescribeJobExecution

    aws iot-jobs-data describe-job-execution ...

  • GetPendingJobExecutions

    aws iot-jobs-data get-pending-job-executions ...

  • StartNextPendingJobExecution

    aws iot-jobs-data start-next-pending-job-execution ...

  • UpdateJobExecution

    aws iot-jobs-data update-job-execution ...

使用 HTTP TLS

Jobs 服务和设备之间的通信可通过端口 8443 上的 HTTP TLS,使用支持此协议的第三方软件客户端进行。

注意

您在通过 HTTP TLS 与 Jobs 进行通信时必须使用正确的终端节点。要查找该终端节点,请使用 DescribeEndpoint 命令。例如,使用以下 CLI:

aws iot describe-endpoint --endpoint-type iot:Jobs

您将获得一个类似于下面的结果:

{ "endpointAddress": "a1b2c3d4e5f6g7.jobs.iot.us-west-2.amazonaws.com" }

利用此方法,您的设备可使用基于身份验证的 X509 证书 (例如,使用其特定于设备的证书和私有密钥)。

可以使用此方法执行以下命令:

  • DescribeJobExecution

  • GetPendingJobExecutions

  • StartNextPendingJobExecution

  • UpdateJobExecution

对设备进行编程以使用 Jobs

本节中的示例使用 MQTT 来演示设备如何使用 Jobs。或者,您也可以按需使用对应的 API 或 CLI 命令。对于这些示例,我们假定一台名为 MyThing 的设备将订阅以下 MQTT 主题:

  • $aws/things/MyThing/jobs/notify (或者 $aws/things/MyThing/jobs/notify-next)

  • $aws/things/MyThing/jobs/get/accepted

  • $aws/things/MyThing/jobs/get/rejected

  • $aws/things/MyThing/jobs/jobId/get/accepted

  • $aws/things/MyThing/jobs/jobId/get/rejected

设备工作流程

通常,设备可通过两种方式处理要执行的任务。

选项 A:获取下一个任务选项 B:从可用任务中选取
选项 A:获取下一个任务
  1. 当设备首次联机时,它应订阅设备的 notify-next 主题。

  2. 使用 jobId $next 调用 DescribeJobExecution MQTT API 以获取下一个任务、其任务文档和其他详细信息,包括保存在 statusDetails 中的任何状态。

  3. 调用 UpdateJobExecution MQTT API 以更新任务状态。或者,要在一个调用中将此步骤与上一步骤合并,设备可调用 StartNextPendingJobExecution

  4. 使用 UpdateJobExecution MQTT API 执行任务文档所指定的操作以报告任务的进度。

  5. 通过使用此 jobId 调用 DescribeJobExecution MQTT API 来继续监控任务执行。如果在设备运行任务时取消或删除了任务执行,则设备应能够恢复到有效状态。

  6. 在任务完成后调用 UpdateJobExecution MQTT API 以更新任务状态并报告成功或失败。

  7. 由于此任务的执行状态已更改为最终状态,因此,可用于执行的下一个任务 (如果有) 将发生更改。设备将收到下一个待处理任务执行已更改的通知。此时,设备将按照步骤 2 中所述继续操作。

如果设备保持联机状态,则它在完成任务或添加新的待处理任务执行时,将继续收到下一个待处理任务执行的通知,包括其 JobExecutionData。在发生此情况时,设备将按照步骤 2 中所述继续操作。

选项 B:从可用任务中选取
  1. 当设备首次联机时,它应订阅事物的 notify 主题。

  2. 调用 GetPendingJobExecutions MQTT API 以获取待处理任务执行的列表。

  3. 如果列表包含一个或多个任务执行,请选取一个任务执行。

  4. 调用 DescribeJobExecution MQTT API 以获取任务文档和其他详细信息,包括保存在 statusDetails 中的任何状态。

  5. 调用 UpdateJobExecution MQTT API 以更新任务状态。如果在此命令中将 includeJobDocument 字段设置为 true,则设备可跳过上一个步骤并在此时检索任务文档。

  6. 使用 UpdateJobExecution MQTT API 执行任务文档所指定的操作以报告任务的进度。

  7. 通过使用此 jobId 调用 DescribeJobExecution MQTT API 来继续监控任务执行。如果在设备运行任务时取消或删除了任务执行,则设备应能够恢复到有效状态。

  8. 在任务完成后调用 UpdateJobExecution MQTT API 以更新任务状态并报告成功或失败。

如果设备保持联机状态,则在一个新的待处理任务执行变为可用时,它将收到所有待处理任务执行的通知。在发生此情况时,设备可按照步骤 2 中所述继续操作。

如果设备无法执行任务,它将调用 UpdateJobExecution MQTT API 来将任务状态更新为 REJECTED

任务通知

当 AWS IoT 任务待处理时,该任务将向预留主题发布 MQTT 消息。设备可通过订阅这些主题来跟踪待处理任务。

有关发布和订阅 MQTT 主题的更多信息,请参阅AWS IoT 的消息代理

注意

当您使用 HTTP SigV4 或 HTTP TLS 与任务通信时,通知不可用。

任务待处理更多信息 (11)
任务待处理

当某个事物的待处理任务执行列表中添加或删除了任务时,或者对列表中任务的顺序有更改时,AWS IoT Jobs 会在 MQTT 主题上发布消息:

  • $aws/things/thingName/jobs/notify

  • $aws/things/thingName/jobs/notify-next

更多信息 (11)

消息包含以下示例负载:

$aws/things/thingName/jobs/notify

{ "timestamp" : 10011, "jobs" : { "IN_PROGRESS" : [ { "jobId" : "other-job", "queuedAt" : 10003, "lastUpdatedAt" : 10009, "executionNumber" : 1, "versionNumber" : 1 } ], "QUEUED" : [ { "jobId" : "this-job", "queuedAt" : 10011, "lastUpdatedAt" : 10011, "executionNumber" : 1, "versionNumber" : 0 } ] } }

$aws/things/thingName/jobs/notify-next

{ "timestamp" : 10011, "execution" : { "jobId" : "other-job", "status" : "IN_PROGRESS", "queuedAt" : 10009, "lastUpdatedAt" : 10009, "versionNumber" : 1, "executionNumber" : 1, "jobDocument" : {"c":"d"} } }

可能的任务执行状态值为 QUEUEDIN_PROGRESSFAILEDSUCCEEDEDCANCELEDREJECTEDREMOVED

以下一系列示例显示了,在创建任务执行和任务执行从一种状态更改为另一种状态时从每个主题发送的通知类型。

首先,您创建一个名为 job1 的任务。您将从 jobs/notify 主题获得此通知:

{ "timestamp": 1517016948, "jobs": { "QUEUED": [ { "jobId": "job1", "queuedAt": 1517016947, "lastUpdatedAt": 1517016947, "executionNumber": 1, "versionNumber": 1 } ] } }

您将从 jobs/notify-next 主题获得此通知:

{ "timestamp": 1517016948, "execution": { "jobId": "job1", "status": "QUEUED", "queuedAt": 1517016947, "lastUpdatedAt": 1517016947, "versionNumber": 1, "executionNumber": 1, "jobDocument": { "operation": "test" } } }

当您创建另一个任务 (job2) 时,您将从 jobs/notify 主题获得此通知:

{ "timestamp": 1517017192, "jobs": { "QUEUED": [ { "jobId": "job1", "queuedAt": 1517016947, "lastUpdatedAt": 1517016947, "executionNumber": 1, "versionNumber": 1 }, { "jobId": "job2", "queuedAt": 1517017191, "lastUpdatedAt": 1517017191, "executionNumber": 1, "versionNumber": 1 } ] } }

您没有从 jobs/notify-next 主题获得通知,因为队列中的下一个任务 (job1) 尚未更改。当 job1 开始执行时,其状态更改为 IN_PROGRESS。没有发送任何通知,因为任务列表和队列中的下一个任务尚未更改。

当您添加第三个任务 (job3) 时,您将从 jobs/notify 主题获得此通知:

{ "timestamp": 1517017906, "jobs": { "IN_PROGRESS": [ { "jobId": "job1", "queuedAt": 1517016947, "lastUpdatedAt": 1517017472, "startedAt": 1517017472, "executionNumber": 1, "versionNumber": 2 } ], "QUEUED": [ { "jobId": "job2", "queuedAt": 1517017191, "lastUpdatedAt": 1517017191, "executionNumber": 1, "versionNumber": 1 }, { "jobId": "job3", "queuedAt": 1517017905, "lastUpdatedAt": 1517017905, "executionNumber": 1, "versionNumber": 1 } ] } }

您没有从 jobs/notify-next 主题获得通知,因为队列中的下一个任务仍是 job1

job1 完成后,其状态更改为 SUCCEEDED,您将从 jobs/notify 主题获得此通知:

{ "timestamp": 1517186269, "jobs": { "QUEUED": [ { "jobId": "job2", "queuedAt": 1517017191, "lastUpdatedAt": 1517017191, "executionNumber": 1, "versionNumber": 1 }, { "jobId": "job3", "queuedAt": 1517017905, "lastUpdatedAt": 1517017905, "executionNumber": 1, "versionNumber": 1 } ] } }

此时,已从队列中删除 job1,要执行的下一个任务是 job2。您将从 jobs/notify-next 主题获得此通知:

{ "timestamp": 1517186269, "execution": { "jobId": "job2", "status": "QUEUED", "queuedAt": 1517017191, "lastUpdatedAt": 1517017191, "versionNumber": 1, "executionNumber": 1, "jobDocument": { "operation": "test" } } }

如果您选择让 job3job2 之前开始执行 (不推荐),可以将 job3 的状态更改为 IN_PROGRESS。如果您执行此操作,则 job2 不再是队列中的下一个任务,您将从 jobs/notify-next 主题获得此通知:

{ "timestamp": 1517186779, "execution": { "jobId": "job3", "status": "IN_PROGRESS", "queuedAt": 1517017905, "startedAt": 1517186779, "lastUpdatedAt": 1517186779, "versionNumber": 2, "executionNumber": 1, "jobDocument": { "operation": "test" } } }

没有向 jobs/notify 发送任何通知,因为没有添加或删除任何任务。

如果 job2 失败并且其状态更改为 REJECTED,您将从 jobs/notify 主题获得此通知:

{ "timestamp": 1517189392, "jobs": { "IN_PROGRESS": [ { "jobId": "job3", "queuedAt": 1517017905, "lastUpdatedAt": 1517186779, "startedAt": 1517186779, "executionNumber": 1, "versionNumber": 2 } ] } }

开始新任务

新任务通知更多信息 (14)
新任务通知

在创建新任务时,Jobs 将在 $aws/things/thing-name/jobs/notify 主题上为每个目标设备发布一条消息。

更多信息 (14)

消息包含以下信息:

{ "timestamp":1476214217017, "jobs":{ "QUEUED":[{ "jobId":"0001", "queuedAt":1476214216981, "lastUpdatedAt":1476214216981, "versionNumber" : 1 }] } }

在对任务执行进行排队时,设备将在“$aws/things/thingName/jobs/notify”主题中收到此消息。

获取任务信息更多信息 (15)
获取任务信息

要获取有关任务执行的更多信息,请调用 DescribeJobExecution MQTT API 并将 includeJobDocument 字段设置为 true。

更多信息 (15)

如果请求成功,Jobs 将在 $aws/things/MyThing/jobs/0023/get/accepted 主题上发布消息:

{ "clientToken" : "client-001", "timestamp" : 1489097434407, "execution" : { "jobId" : "023", "status" : "QUEUED", "queuedAt" : 1489097374841, "lastUpdatedAt" : 1489097374841, "versionNumber" : 1, "jobDocument" : { < contents of job document > } } }

注意

如果请求失败,Jobs 将在 $aws/things/MyThing/jobs/0023/get/rejected 主题上发布消息。

设备现在已有任务文档,它可解释该文档以执行任务的远程操作。如果任务文档包含一个 Amazon S3 预签名 URL,则设备可使用该 URL 下载任务的任何所需文件。

设备可调用 StartNextPendingJobExecution MQTT API 来通过一个步骤请求更多信息并开始任何待处理任务执行。

报告任务执行状态

更新执行状态更多信息 (16)
更新执行状态

当设备执行任务时,它可调用 UpdateJobExecution MQTT API 来更新任务执行的状态。

更多信息 (16)

例如,设备可通过在 $aws/things/MyThing/jobs/0023/update 主题上发布以下消息来将任务执行状态更新为 IN_PROGRESS

{ "status":"IN_PROGRESS", "statusDetails": { "progress":"50%" }, "expectedVersion":"1", "clientToken":"client001" }

Jobs 通过将消息发布到 $aws/things/MyThing/jobs/0023/update/accepted$aws/things/MyThing/jobs/0023/update/rejected 主题来做出响应:

{ "clientToken":"client001", "timestamp":1476289222841 }

设备可通过调用 StartNextPendingJobExecution 来合并两个以前的请求,这将获取并开始下一个待处理任务执行,并允许设备更新任务执行状态。此请求还在有待处理任务执行时返回任务文档。

status 字段可设置为 QUEUEDIN_PROGRESSSUCCESSFAILEDREJECTEDREMOVEDCANCELED。您无法更新已处于最终状态的任务执行的状态。

报告执行已完成更多信息 (17)
报告执行已完成

在设备执行完任务后,它将调用 UpdateJobExecution MQTT API。如果任务已成功,则将 status 设置为 SUCCESS,并在消息负载的 statusDetails 中,将有关任务的其他信息作为名称/值对添加。

更多信息 (17)

例如:

{ "status":"SUCCESS", "statusDetails": { "progress":"100%" }, "expectedVersion":"2", "clientToken":"client-001" }

如果任务未成功,则将 status 设置为 FAILED,并在 statusDetails 中,添加有关出现的错误的信息:

{ "status":"FAILED", "statusDetails": { "errorCode":"101", "errorMsg":"Unable to install update" }, "expectedVersion":"2", "clientToken":"client-001" }

注意

statusDetails 属性可包含任意数量的名称/值对。

在 Jobs 检索此更新时,它会在 $aws/things/MyThing/jobs/notify 主题上发布消息以指示任务执行已完成:

{ "timestamp":1476290692776, "jobs":{} }

其他任务

其他任务更多信息 (18)
其他任务

如果设备有其他待处理的任务执行,这些任务执行将包含在发布到 $aws/things/MyThing/jobs/notify 的消息中。

更多信息 (18)

例如:

{ "timestamp":1476290692776, "jobs":{ "QUEUED":[{ "jobId":"0002", "queuedAt":1476290646230, "lastUpdatedAt":1476290646230 }], "IN_PROCESS":[{ "jobId":"0003", "queuedAt":1476290646230, "lastUpdatedAt":1476290646230 }] } }