AWS IoT
平台架构
AWS服务
- Amazon DynamoDB—托管NoSQL数据库
- Amazon Kinesis—大规模流式数据实时处理
- AWS Lambda—EC2云虚拟机运行代码响应事件
- Amazon Simple Storage Service(S3)—可扩展云存储
- Amazon Simple Notification—推送通知服务
- Amazon Simple Queue Service—消息队列服务
SDK
- AWS IoT 设备 SDK 使用 MQTT、HTTP 或 WebSockets 协议将硬件设备连接到 AWS IoT,硬件设备无缝安全地与 AWS IoT 提供的设备网关和设备影子协作。
- 设备 SDK 支持 C、JavaScript 、Arduino、Java和Python。
- 设备 SDK 包含开源库、带有示例的开发人员指南和移植指南,用户根据硬件平台构建 IoT 产品或解决方案。
设备网关
- AWS IoT 设备网关支持设备安全高效地与 AWS IoT 进行通信。设备网关可以使用发布/订阅模式交换消息,从而支持一对一和一对多的通信。凭借此一对多的通信模式,AWS IoT 将支持互连设备向多名给定主题的订阅者广播数据。
- 设备网关支持 MQTT、WebSocket 和 HTTP 1.1 协议,也支持私有协议。
- 设备网关可自动扩展,以支持 10 亿多台设备,而无需预配置基础设施。
认证和授权
- AWS IoT 在所有连接点处提供相互身份验证和加密。AWS IoT 支持 AWS 身份验证方法(称为"SigV4")以及基于身份验证的 X.509 证书。使用 HTTP 的连接可以使用任一方法,使用 MQTT 的连接可以使用基于证书的身份验证,使用 WebSockets 的连接可以使用 SigV4。
- 使用 AWS IoT 生成的证书以及由首选证书颁发机构 (CA) 签署的证书,将所选的角色和/或策略映射到每个证书,以便授予设备或应用程序访问权限,或撤消访问权限。
- 通过控制台或使用 API 创建、部署并管理设备的证书和策略。这些设备证书可以预配置、激活和与使用 AWS IAM 配置的相关策略关联。
- AWS IoT 还支持用户移动应用使用 Amazon Cognito 进行连接,Amazon Cognito 将负责执行必要的操作来为应用用户创建唯一标识符并获取临时的、权限受限的 AWS 凭证
注册表
- 注册表将创建设备标识并跟踪元数据,如设备的属性和功能。
- 注册表向格式一致的每台设备分配唯一的标识,而不管设备的类型和连接方式为何。此外,它还支持描述设备功能的元数据,例如传感器是否报告温度,以及数据是华氏度还是摄氏度。
- 注册表存储有关设备的元数据,无需支付额外费用;并且需要每隔 7 天至少访问或更新注册表条目一次,注册表中的元数据就不会过期。
以JSON格式存储的设备注册表信息
Shadow
Shadow服务用途
设备的影子 是用于存储和检索设备的当前状态信息的 JSON 文档。Device Shadow 服务可以为您连接到 AWS IoT 的每台设备保留一个影子。您可以使用该影子通过 MQTT 或 HTTP 获取和设置设备的状态,无论该设备是否连接到 Internet。每台设备的影子都由相应事物的名称唯一标识。
- 设备影子保留每台设备的最后报告状态和期望的未来状态,即便设备处于离线状态。
- 通过 API 或使用规则引擎,获取设备的最后报告状态或设置期望的未来状态。
- 应用程序可以设置设备的期望未来状态,而无需说明设备的当前状态。AWS IoT 将比较期望未来状态和最后报告状态之间的差异,并命令设备"弥补差异"。
- 设备 SDK 能够轻松地同步其状态及其影子,并响应通过影子设置的期望的未来状态。
- 设备影子免费存储设备状态多达一年。如果至少每年更新一次状态,则设备影子将永久保留状态;否则状态将过期。
影子服务
设备影子服务使用MQTT话题,便于应用和设备之间的通信,下面是相关的MQTT QoS 1话题:
$aws/things/{thingName}/shadow/update
$aws/things/{thingName}/shadow/get
$aws/things/{thingName}/shadow/delete
$aws/things/{thingName}/shadow/update/accepted
$aws/things/{thingName}/shadow/update/rejected
$aws/things/{thingName}/shadow/update/delta
$aws/things/{thingName}/shadow/get/accepted
$aws/things/{thingName}/shadow/get/rejected
$aws/things/{thingName}/shadow/delete/accepted
$aws/things/{thingName}/shadow/delete/rejected
设备SDK(C-SDK、JS-SDK)将影子功能内置在设备中,能够使设备与影子服务之间自动同步状态。
控制模型
控制灯泡
工作原理
1.连接着的 Led 灯发送封装在MQTT消息中的 reported 状态 『off』 到 AWS IoT 2.AWS IoT 通过 led 灯使用的证书来确定它所属的虚拟事物 3.AWS IoT 将 reported 状态保存在设备影子 JSON 文件中 4.一条 AWS IoT rule 正监控着 led 的 off 状态,它发送一个消息到某个 SNS topic 5.某 application 收到 SNS 消息。用户将 led 期望状态(desired state)设置为 on 6. AWS IoT 收到该消息,它更新设备影子中的 desired state,同时发送包含期望状态的 message 到某些topic。此时,reported 和 desired 状态是 『Out of Sync』的 7. led 收到 delta 消息,开始根据其中的 desired status 来设置其实际状态 8. led 将其状态设置为 on,向 MQTT topic 发送新的 reported 状态 9. AWS IoT 更新设备影子,现在该设备的 reported 和 desired 状态一致了
格式
关键属性
影子文档属性
设备的影子文档具有以下属性:
- state
desired 事物的预期状态。应用程序可以向本文档部分写入数据来更新事物的状态,且无需直接连接到该事物。
reported 事物的报告状态。事物可以向本文档部分写入数据,以报告其新状态。应用程序可以读取本文档部分,以确定事物的状态。
metadata 有关存储在文档 state 部分的数据的信息,其中包括 state 部分中每个属性的时间戳(以 Epoch 时间表示),让您能够确定它们的更新时间。
timestamp 指明 AWS IoT 传输消息的时间。通过在消息中使用时间戳并对 desired 或 reported 部分中的不同属性使用时间戳,事物可以确定已更新项目的存在时间,即使它不具有内部时钟特性。
clientToken 特定于设备的字符串,让您能在 MQTT 环境中将响应与请求关联起来。
version 文档版本。文档每次更新时,此版本号都会递增。用于确保正在更新的文档为最新版本。
影子文档语法
请求结构
{
"state": {
"desired": {
"attribute1": integer2,
"attribute2": "string2",
...
"attributeN": boolean2
},
"reported": {
"attribute1": integer1,
"attribute2": "string1",
...
"attributeN": boolean1
}
}
"clientToken": "token",
"version": version
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
响应状态
{
"state": {
"desired": {
"attribute1": integer2,
"attribute2": "string2",
...
"attributeN": boolean2
},
"reported": {
"attribute1": integer1,
"attribute2": "string1",
...
"attributeN": boolean1
},
"delta": {
"attribute3": integerX,
"attribute5": "stringY"
}
},
"metadata": {
"desired": {
"attribute1": {
"timestamp": timestamp
},
"attribute2": {
"timestamp": timestamp
},
...
"attributeN": {
"timestamp": timestamp
}
},
"reported": {
"attribute1": {
"timestamp": timestamp
},
"attribute2": {
"timestamp": timestamp
},
...
"attributeN": {
"timestamp": timestamp
}
}
},
"timestamp": timestamp,
"clientToken": "token",
"version": version
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
错误响应
{
"code": error-code,
"message": "error-message",
"timestamp": timestamp,
"clientToken": "token"
}
2
3
4
5
6
预留主题
aws Iot预留了一些主题,预留的主题以$开头。除非下面列出的主题之外,不支持用于进行发布和订阅。在任何其他以 $ 开头的主题中尝试发布或订阅将导致连接被终止。
主题 | 允许的操作 | 描述 |
---|---|---|
$aws/events/presence/connected/clientId | Subscribe | 当使用特定客户端 ID 的 MQTT 客户端连接至 AWS IoT 时,AWS IoT 将向此主题发布。有关更多信息,请参阅 连接/断开连接事件。 |
$aws/events/presence/disconnected/clientId | Subscribe | 当使用特定客户端 ID 的 MQTT 客户端与 AWS IoT 断开连接时,AWS IoT 将向此主题发布。有关更多信息,请参阅 连接/断开连接事件。 |
$aws/events/subscriptions/subscribed/clientId | Subscribe | 当使用特定客户端 ID 的 MQTT 客户端订阅 MQTT 主题时,AWS IoT 将向此主题发布。有关更多信息,请参阅 订阅/取消订阅事件。 |
$aws/events/subscriptions/unsubscribed/clientId | Subscribe | 当使用特定客户端 ID 的 MQTT 客户端取消订阅 MQTT 主题时,AWS IoT 将向此主题发布。有关更多信息,请参阅 订阅/取消订阅事件。 |
$aws/things/thingName/shadow/delete | 发布/订阅 | 设备或应用程序向此主题发布消息以删除影子。有关更多信息,请参阅 http://docs.aws.amazon.com/iot/latest/developerguide//device-shadow-mqtt.html#delete-pub-sub-topic。 |
$aws/things/thingName/shadow/delete/accepted | Subscribe | 当一个影子被删除时,Device Shadow 服务将向此主题发送消息。有关更多信息,请参阅 http://docs.aws.amazon.com/iot/latest/developerguide//device-shadow-mqtt.html#delete-accepted-pub-sub-topic。 |
$aws/things/thingName/shadow/delete/rejected | Subscribe | 当删除影子的请求遭拒时,Device Shadow 服务将向此主题发送消息。有关更多信息,请参阅 http://docs.aws.amazon.com/iot/latest/developerguide//device-shadow-mqtt.html#delete-rejected-pub-sub-topic。 |
$aws/things/thingName/shadow/get | 发布/订阅 | 应用程序或事物向此主题发布空消息来获取影子。有关更多信息,请参阅 http://docs.aws.amazon.com/iot/latest/developerguide//device-shadow-mqtt.html。 |
$aws/things/thingName/shadow/get/accepted | Subscribe | 当获取影子的请求获批时,Device Shadow 服务将向此主题发送消息。有关更多信息,请参阅 http://docs.aws.amazon.com/iot/latest/developerguide//device-shadow-mqtt.html#get-accepted-pub-sub-topic。 |
$aws/things/thingName/shadow/get/rejected | Subscribe | 当获取影子的请求遭拒时,Device Shadow 服务将向此主题发送消息。有关更多信息,请参阅 http://docs.aws.amazon.com/iot/latest/developerguide//device-shadow-mqtt.html#get-rejected-pub-sub-topic。 |
$aws/things/thingName/shadow/update | 发布/订阅 | 事物或应用程序向此主题发布消息以更新影子。有关更多信息,请参阅 http://docs.aws.amazon.com/iot/latest/developerguide//device-shadow-mqtt.html#update-pub-sub-topic。 |
$aws/things/thingName/shadow/update/accepted | Subscribe | 当影子更新成功时,Device Shadow 服务将向此主题发送消息。有关更多信息,请参阅 http://docs.aws.amazon.com/iot/latest/developerguide//device-shadow-mqtt.html#update-accepted-pub-sub-topic。 |
$aws/things/thingName/shadow/update/rejected | Subscribe | 当影子更新遭拒时,Device Shadow 服务将向此主题发送消息。有关更多信息,请参阅 http://docs.aws.amazon.com/iot/latest/developerguide//device-shadow-mqtt.html#update-rejected-pub-sub-topic。 |
$aws/things/thingName/shadow/update/delta | Subscribe | 当检测到影子的“reported”部分与“desired”部分之间存在差异时,Device Shadow 服务将向此主题发送消息。有关更多信息,请参阅 http://docs.aws.amazon.com/iot/latest/developerguide//device-shadow-mqtt.html#update-delta-pub-sub-topic。 |
$aws/things/thingName/shadow/update/documents | Subscribe | 每次影子更新成功执行时,AWS IoT 都会向该主题发布状态文档。有关更多信息,请参阅 http://docs.aws.amazon.com/iot/latest/developerguide//device-shadow-mqtt.html#update-documents-pub-sub-topic。 |
Sample 程序
basicPubSub.py
这个程序可以作publish也可以作subscribe,或者同时运行。
当publish时 每隔1s产生一个消息
loopCount = 0
while True:
if args.mode == 'both' or args.mode == 'publish':
message = {}
message['message'] = args.message
message['sequence'] = loopCount
messageJson = json.dumps(message)
myAWSIoTMQTTClient.publish(topic, messageJson, 1)
if args.mode == 'publish':
print('Published topic %s: %s\n' % (topic, messageJson))
loopCount += 1
time.sleep(1)
2
3
4
5
6
7
8
9
10
11
12
13
当作subscribe时,由于注册了calback函数,在收到消息时候会有一个调用
def customCallback(client, userdata, message):
print("Received a new message: ")
print(message.payload)
print("from topic: ")
print(message.topic)
print("--------------\n\n")
# Connect and subscribe to AWS IoT
myAWSIoTMQTTClient.connect()
if args.mode == 'both' or args.mode == 'subscribe':
myAWSIoTMQTTClient.subscribe(topic, 1, customCallback)
time.sleep(2)
2
3
4
5
6
7
8
9
10
11
12
13
14
输出如下:
2018-08-16 17:23:51,459 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Invoking custom event callback...
2018-08-16 17:23:56,435 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [message] event
2018-08-16 17:23:56,435 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [message] event
Received a new message:
b'{"message": "Hello World!", "sequence": 18}'
from topic:
sdk/test/Python
--------------
2
3
4
5
6
7
8
9
basicPubSubAsync.py
注意ackCallback与messageCallback区别
ackCallback - Callback to be invoked when the client receives a SUBACK. Should be in form messageCallback - Function to be called when a new message for the subscribed topic comes in.
SUBACK: 服务端发送SUBACK报文给客户端,用于确认它已收到并且正在处理SUBSCRIBE报文。简单理解为服务器端通知订阅客户端"我知道你要订阅了"
详细参考:https://mcxiaoke.gitbooks.io/mqtt-cn/content/mqtt/0309-SUBACK.html
异常
sample程序可能会遇到exception,这多数是授权策略引起的。开发调试状态下
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:*"
],
"Resource": [
"*"
]
}
]
}
2
3
4
5
6
7
8
9
10
11
12
13
14