简介
当客户购买设备回家,第一件事就是配网,所以配网是所有物理网公司和客户建立Link的第一步, 我们来看看如何在亚马逊云上构建设备配网。
如图:
- 用户使用手机输入用户名密码登录后,用户中心返回用户 uuid 和 IoT thing 注册地址
- 登录后从Cognito 拿到用户ID
- 手机将路由器ssid、WIFI 密码、和设备注册地址通过蓝牙协议传输给设备,设备本身将mac地址返回手机端
- 使用设备的MAC和设备序列号请求设备中
- 配置中心创建 thing ,并生成 iot core policy
- 配置中心返回证书、iot endpoint 等设备连接iot core 配置
- 设备重启后连接iot core
- 手机使用设备端返回的mac地址进行配网
配置基础环境
安装配置 AWS CLI
安装
参考 AWS 命令行界面 安装
Win 下载 https://s3.amazonaws.com/aws-cli/AWSCLI64.msi 安装
Mac/Linux 执行 npm install awscli (首先初始化 node)
配置 AWS CLI
aws configure
输入 AWS Access Key ID = (aws子账户id)
AWS Secret Access Key = (aws子账户密钥)
region name = ap-southeast-1(region )
用户中心构建
Cognito UserPool
用户池是 Amazon Cognito 中的用户目录。利用用户池,您的用户可以通过 Amazon Cognito 登录您的 Web 或移动应用程序。您的用户还可以通过社交身份提供商(例如 Google、Facebook、Amazon 或 Apple)以及 SAML 身份提供商登录。无论您的用户是直接登录还是通过第三方登录,用户池的所有成员都有一个可通过软件开发工具包 (SDK) 访问的目录配置文件。
- 注册和登录服务。
- 用于登录用户的内置的、可自定义的 Web UI。
- 使用 Facebook、Google、Login with Amazon 和 Sign in with Apple 的社交登录,以及使用您的用户池中的 SAML 身份提供商的登录。
- 用户目录管理和用户配置文件。
- 多重身份验证(MFA)、遭盗用凭证检查、账户盗用保护以及电话和电子邮件验证等安全功能。
- 通过 AWS Lambda 触发器进行的自定义工作流程和用户迁移。
这里我们使用它托管的“注册和登录服务” 功能。
- 创建Cognito user pool
打开cognito
输入user pool 名称
配置属性
配置密码强度
创建手机端 clientId
- 创建测试用户
secret_hash.py
import sys
import hmac, hashlib, base64
username = sys.argv[1]
app_client_id = sys.argv[2]
key = sys.argv[3]
message = bytes(sys.argv[1]+sys.argv[2],'utf-8')
key = bytes(sys.argv[3],'utf-8')
secret_hash = base64.b64encode(hmac.new(key, message, digestmod=hashlib.sha256).digest()).decode()
print("SECRET HASH:",secret_hash)
python3 secret_hash.py admin@example.com 7qndvi6p81q81eii0fou6cnf25 19dfu6oq5lgiqtkbvl9c34hn3mneh6urnld32hur4t4geps5cht5
## 创建测试用户
aws cognito-idp sign-up \
--client-id 7qndvi6p81q81eii0fou6cnf25 \
--username admin@example.com \
--password Passw0rd! \
--user-attributes Name=email,Value=admin@example.com \
--secret-hash bZAuMqn37JEaIOsXq+1R/lj3RsKyqd628Wo8HSZhXb0= \
--region ap-southeast-1 \
--profile default
## confirm
aws cognito-idp admin-confirm-sign-up \
--user-pool-id ap-southeast-1_QMJDnesBF \
--username admin@example.com \
--region ap-southeast-1 \
--profile default
- 登录拿到 token 和 sub
from pycognito import Cognito
def auth():
u = Cognito('ap-southeast-1_QMJDnesBF','7qndvi6p81q81eii0fou6cnf25', client_secret='19dfu6oq5lgiqtkbvl9c34hn3mneh6urnld32hur4t4geps5cht5',
username='kkk999')
u.authenticate(password='12345678')
u.id_token
u.access_token
u.refresh_token
print(u.get_user().sub)
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
print('Test')
auth()
subid:807915e2-b597-440a-8417-cee4927d3d06
设备中心构建
设备中心主要职责是:设备在云端的创建,证书下载等功能。在亚马逊云上我们选择全套serverless 的服务:apigetway, lambda,dynamodb 帮大家快速构建。
准备工作
- 创建存放证书 S3 桶
aws s3 mb s3://cconfig-certificate --region ap-southeast-1
- 创建lambda Role , Role name “iot_lambda_role”
## 1 创建 policy "iot_lambda_policy"
aws iam create-policy --region ap-southeast-1 --policy-name iot_lambda_policy --policy-document '{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "iot:*", "s3:*", "dynamodb:*"], "Resource": "*" } ] }'
## 2 binding iot_lambda_policy to iot_lambda_role
aws iam create-role --role-name iot_lambda_role --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }'
aws iam attach-role-policy --policy-arn arn:aws:iam::964479626419:policy/iot_lambda_policy --role-name iot_lambda_role
- 创建 dynamodb
3.1 创建 dynamodb table
3.2 配置索引
- Get IoT code endpoint
aws iot describe-endpoint --endpoint-type iot:Data-ATS --region ap-southeast-1
WorkFlow
- 用户在配网前已经登录平台
- 在用户请求时会带上token,平台通过token识别用户
部署服务
- Github clone Https://github.com/jianyew/CloudConfig_lambda_core.git,根据上面配置信息, 修改工程相关配置。
- 根据readme deploy到亚马逊云平台
打包
创建s3 储存通
aws s3 mb s3://cloudconfig-mydemo-app --region ap-southeast-1
进入项目根目录
本地打包
mvn package
cloudformation打包
aws cloudformation package --template-file sam.yaml --output-template-file output-sam.yaml --s3-bucket cloudconfig-mydemo-app
部署lambda函数
aws cloudformation deploy --template-file output-sam.yaml --stack-name cloudconfig-mydemo-app --capabilities CAPABILITY_NAMED_IAM --region=ap-southeast-1
获取应用信息
aws cloudformation describe-stacks --stack-name cloudconfig-mydemo-app --region=ap-southeast-1
- apigetway endpoint
- 关键API说明:
根据当前登录用户注册设备
curl -X POST https://5iryyf3qli.execute-api.ap-southeast-1.amazonaws.com/Prod/device/register?productKey=001&mac=2af8bc6ad9a3
自动生Thing和证书
同时生成对应证书的policy
binding 设备
curl -X POST https://5iryyf3qli.execute-api.ap-southeast-1.amazonaws.com/Prod/user/device/bind?mac=2af8bc6ad9a3&deviceNickName=mydevice01
在dynamodb 生成user和device 的mapping关系
查看当前用户设备:
curl -X GET https://5iryyf3qli.execute-api.ap-southeast-1.amazonaws.com/Prod/user/device/list
测试
- 下载证书
rootCA 下载:https://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/server-authentication.html
- 使用python模拟模组,测试发送消息
#!/usr/bin/python3
import sys
import ssl
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
import json
import time
#Setup our MQTT client and security certificates
#Make sure your certificate names match what you downloaded from AWS IoT
mqttc = AWSIoTMQTTClient("2AF8BC6AD9A2")##设置clienid
#Use the endpoint from the settings page in the IoT console
mqttc.configureEndpoint("a1w6jnzc1m4aj1-ats.iot.ap-southeast-1.amazonaws.com",8883)
mqttc.configureCredentials("AmazonRootCA1.pem","2AF8BC6AD9A2_privateKey.pem","2AF8BC6AD9A2_certificatePem.pem")
##配置证书
#Function to encode a payload into JSON
def json_encode(string):
return json.dumps(string)
mqttc.json_encode=json_encode
#This sends our test message to the iot topic
def send(i):
#Declaring our variables
message ={
'thing': "device01",
'no': i,
'ct': time.asctime(time.localtime(time.time()) ),
'message': "Test Message"
}
#Encoding into JSON
message = mqttc.json_encode(message)
mqttc.publish("999999/2AF8BC6AD9A2/", message, 1)
print ("Message Published " + message)
#Connect to the gateway
mqttc.connect()
print ("Connected")
i=0
#Loop until terminated
while True:
i = i +1
send(i)
time.sleep(5)
#send(i)
mqttc.disconnect()
- 查询用户的devices
本篇作者