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

设备和任务

device communication with Jobsusing the MQTT protocolusing HTTP SigV4using HTTP TLS
device communication with Jobs

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

  • MQTT

  • HTTP SigV4

  • HTTP TLS

using the MQTT protocol

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 DescribeJobExecution 调用 $next API 来检索下一个待处理任务执行。

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

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

using 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 ...

using 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

设备工作流程

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

Option A: Get the next jobOption B: Pick from available jobs
Option A: Get the next job
  1. 当设备首次联机时,它应订阅设备的 notify-next 主题。

  2. 使用 jobId DescribeJobExecution 调用 $next 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 中所述继续操作。

Option B: Pick from available jobs
  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

开始新任务

new job notificationmore info (15)
new job notification

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

more info (15)

消息包含以下信息:

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

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

get job informationmore info (16)
get job information

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

more info (16)

如果请求成功,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 下载作业的任何所需文件。

报告任务执行状态

update execution statusmore info (17)
update execution status

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

more info (17)

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

{ "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。您无法更新已处于最终状态的任务执行的状态。

report execution completedmore info (18)
report execution completed

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

more info (18)

例如:

{ "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":{} }

其他任务

additional jobsmore info (19)
additional jobs

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

more info (19)

例如:

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

任务通知

当作业待处理或列表中的首个作业执行有更改时,AWS IoT Jobs 将向预留主题发布 MQTT 消息。设备可通过订阅这些主题来跟踪待处理任务。

作业通知将作为 JSON 负载发布到 MQTT 主题。通知有两种:

  1. ListNotificationListNotification 包含一个列表,其中待处理的作业执行不超过 10 个。此列表中作业执行的状态值为 IN_PROGRESSQUEUED。它们依次按照状态(IN_PROGRESS 作业执行在 QUEUED 作业执行之前)和排队的时间进行排序。

    如果满足以下条件之一,则发布 ListNotification

    1. 新的作业执行已排队或更改为非最终状态(IN_PROGRESSQUEUED)。

    2. 旧的作业执行更改为最终状态(FAILEDSUCCEEDEDCANCELEDREJECTEDREMOVED)。

  2. NextNotificationNextNotification 包含队列中下一个作业执行的摘要信息。

    每当列表中第一个作业执行更改时,则会发布 NextNotification

    1. 新的作业执行作为 QUEUED 被添加到列表,并且在列表中排在第一。

    2. 不是列表第一的现有作业执行的状态从 QUEUED 更改为 IN_PROGRESS,然后成为列表中的第一个。(当列表中没有其他 IN_PROGRESS 作业执行时,或者当状态从 QUEUED 更改为 IN_PROGRESS 的作业执行排队的时间早于列表中其他所有 IN_PROGRESS 作业执行时,会出现这种情况。)

    3. 列表第一的作业执行状态更改为最终状态,并且从列表中删除。

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

注意

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

job pendingmore info (11)
job pending

当某个事物的待处理作业执行列表中添加或删除了作业时,或者列表中的第一个作业执行更改时,AWS IoT Jobs 会在 MQTT 主题上发布消息:

  • $aws/things/thingName/jobs/notify

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

more info (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" } } }

如果 job3 需要在 job2 之前开始执行(不推荐),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 } ] } }

如果 job3(仍在进行)被强制删除,则此通知将发布到 jobs/notify 主题:

{ "timestamp": 1517189551, "jobs": {} }

此时队列为空。该通知发布到 jobs/notify-next 主题:

{ "timestamp": 1517189551 }