IoT Hub是在Azure上所有IoT解决方案都必须要用的核心服务。IoT Hub是一个云网关,它支持多种协议设备接入、设备管理以及IoT数据和控制指令的双向收发。IoT Hub不仅仅是一个MQTT broker,内置了一个Event Hub消息队列可以缓存最多7天的数据,支持Device Twin存储设备的metadata和长期状态。IoT Hub具备多种连接其他Azure服务的接口,用户可以结合Azure上其他存储、分析、机器学习等服务实现一个完整的IoT解决方案。
IoT Hub DPS是IoT Hub的一个配套服务,负责帮助简化在设备和服务端的Provisioning工作。通过DPS支持包括X509证书和TPM2.0在内的高安全的认证设备身份,能根据灵活的规则动态分配设备到不同的IoT Hub,无需用户干预的自动注册设备。
Device Twin顾名思义是设备在云上的孪生体,也可以成为设备影子。它是一个JSON文档存放在IoT Hub中,保存着每个设备的metadata信息,设备端和云端分别可以读写它的某一部分内容:
💡用户可以把Device Twin当做设备的云上配置文件使用,有需要掉电保存的状态可以写入到Twin中,每次上电再从IoT Hub上读取状态。
💡很多IoT Hub相关的功能,包括IoT Edge,OTA,Defender等都用到了Device Twin。
Azure Portal左侧导航栏选择Create a resource,在Internet of Things分类中选择IoT Hub点击Create开启创建向导
Subscription和Resource group分别选择实验订阅和资源组
IoT Hub name输入一个独一无二的的名称,比如iot-lab-hub-<your-name>
,它会成为IoT hub URL的前缀:iot-lab-hub-<your-name>.azure-devices.net
Region选择East Asia
点击Review + Create->Create创建IoT Hub服务
💡当你没有蜂窝网关硬件而选择使用Pi-Simulator来进行此实验的时,跳过第2)、3)、4)步操作,直接看这里。
回到Internet of Things分类中选择IoT Hub Device Provisioning Service点击Create开启创建向导
Subscription和Resource group分别选择实验订阅和资源组
Name输入一个独一无二的名称,比如iot-lab-dps-<your-name>
,它会成为IoT hub DPS URL的前缀:iot-lab-dps-<your-name>.azure-devices-provisioning.net
Region选择East Asia
点击Review + Create->Create创建IoT Hub DPS服务
进入刚刚创建的IoT Hub DPS服务,左侧导航栏选择Linked IoT hubs,点击Add
在打开的窗口中,选择订阅和上一步创建的IoT Hub,点击Save
回到IoT Hub DPS服务,左侧导航栏选择Certificates,点击Add
在打开的窗口中,Certificate name填写一个名称,比如iot-lab-root
,选择实验指南根本目录下的RootCA.cer证书并勾选Set certificate status to verified on upload,点击Save上传并信任证书
💡勾选Set certificate status to verified on upload省略随机数密钥挑战的步骤,但这样做法需要你确认上传的证书是绝对可信的。
回到IoT Hub DPS服务,左侧导航栏选择Manage enrollments,点击Add enrollment group
Group name输入一个名称,比如iot-lab-enroll-group
Attestation Type选择Certificate
IoT Edge Device选择False
Certificate Type选择CA Certficiate
Primary Certificate下拉菜单中选择刚刚上传的iot-lab-root CA证书
Select how you want to assign devices to hubs选择Static Conifguration
Select the IoT hubs this group can be assigned to选择上一步的创建的IoT hub
Initial Device Twin State中填写以下JSON,以确保蜂窝网关注册到IoT Hub后能够默认开始从CAN总线上采集温湿度数据,以60秒的间隔发送到IoT Hub
{
"tags": {},
"properties": {
"desired": {
"devconfig": {
"devMsgInterval": 60,
"canMsgInterval": 60
},
"canconfig": {
"type": "PGN",
"bps": 250,
"cycle": {
"c1": 65257
}
}
}
}
}
Enable entry保持Enable
,点击Save创建enrollment group
这一步通过使用蜂窝网关自带的网页服务器配置IoT Hub DPS ID Scope,使设备能连接到上一步创建的IoT hub DPS服务。
启动实验箱电源,连接PC到AzLek_XX
的WiFi热点,密码为azurelektec
使用浏览器打开192.168.4.1
进入配置网页服务器
在Azure IoT DPS配置中,填入ID Scope后点击设置,ID Scope可以在DPS服务的页面右侧找到,比如0ne0061ABC8
关闭电源重启蜂窝网关
💡实验用的每一个蜂窝网关已经预置了独有的ECC私钥和证书,你也可以使用第三方CA签发的设备证书,或者使用OpenSSL在本地生成用于测试目的的根证书和设备证书/私钥。在上一步中导入自己的根证书(而非实验提供的根证书),并通过配置网页服务器上传设备证书/私钥到自己的设备上。
如果选择使用Pi-Simulator来进行此实验的时,你需要在IoT hub中手动注册设备,配置Device Twin:
进入之前创建的IoT hub服务,左侧导航栏在Device management下选择Devices,在新开的页面中点击 + ADD Device,再从Create a device页面中输入一个Device ID,其他设置项保持不变,点击Save创建设备。
点击新建的设备,选择Device Twin,在新开的窗口中可以看到Device Twin的完整JSON文档,接下来修改Desired字段,增加以下配置信息,点击Save保存。
"desired": {
"devconfig": {
"devMsgInterval": 60,
"canMsgInterval": 60
},
"canconfig": {
"type": "PGN",
"bps": 250,
"cycle": {
"c1": 65257
}
}
}
返回设备页面,中复制它的Primary Connection String。
进入Pi-Simulator,适配实验的代码在这里可以获得,把它复制粘贴到代码区域。
替换代码中的connectionstring
的变量,点击Run开始模拟发送数据。
在默认的情况下,IoT Hub将它所有收到的遥测数据自动存入内置的Event Hub终结点中。Event Hub是一个消息队列服务,它最多支持缓存近7天的数据以供客户端读取和回放。我们可以使用SDK或者调试工具来观察蜂窝网关发送的原始数据。为了避免安装软件,本节实验我们使用Azure Portal上的Azure Cloud Shell中的AZ CLI命令进行演示:
💡由于Azure Cloud Shell需要用到Azure Storage/File Share才存储文件和日志信息,只有第一次激活的时候才会有下面的配置Storage的步骤。
在Portal上方蓝色状态条上找到命令行的图标,点击启动Azure Cloud Shell。
选择Bash进入后在点击Show advanced settings进入配置窗口
Subscription和Resource group分别选择实验订阅和资源组
Cloud Shell region选择East Asia
Storage account选择Use existing,在下拉框中选中之前创建的iot-lab-storage-<your-name>
File share输入任意名称,点击Create Storage开始创建Cloud Shell
Cloud Shell创建完成后会停留在终端上,我们输入AZ CLI命令来查看,输入命令
az iot hub monitor-events -n <your-iot-hub-name> -d <your-device-id>
💡
<your-iot-hub-name>
只取IoT hub URL前缀部分。
第一使用该命令会提示需要安装azure-iot扩展,输入多次y确认继续安装
安装完成后等待出现提示字符串Starting event monitor, filtering on device: <your-device>, use ctrl-c to stop...
,等待片刻会将收到的数据打印在Cloud Shell终端:
{
"event": {
"origin": "<your-device>",
"module": "",
"interface": "",
"component": "",
"payload": "{\"common\":{\"tsp\":[0,22,6,8,18,57,40],\"did\":\"89860476262091398282\",\"gnss\":{\"vld\":false,\"lon\":0,\"lat\":0,\"alt\":0,\"sat\":0,\"hdop\":0}},\"type\":\"cycDev\",\"payload\":{\"soc\":0,\"csq\":23,\"extV\":12.630000114440918,\"lockSt\":false,\"altTime\":120360}}"
}
}