亚马逊AWS官方博客

智能家居物联网平台之 —— 模组配网

 

简介

当客户购买设备回家,第一件事就是配网,所以配网是所有物理网公司和客户建立Link的第一步, 我们来看看如何在亚马逊云上构建设备配网。

如图:

  1. 用户使用手机输入用户名密码登录后,用户中心返回用户 uuid 和 IoT thing  注册地址
  2. 登录后从Cognito 拿到用户ID
  3. 手机将路由器ssid、WIFI 密码、和设备注册地址通过蓝牙协议传输给设备,设备本身将mac地址返回手机端
  4. 使用设备的MAC和设备序列号请求设备中
  5. 配置中心创建 thing ,并生成 iot core policy
  6. 配置中心返回证书、iot endpoint 等设备连接iot core 配置
  7. 设备重启后连接iot core
  8. 手机使用设备端返回的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 触发器进行的自定义工作流程和用户迁移。

这里我们使用它托管的“注册和登录服务” 功能。

  1. 创建Cognito user pool

打开cognito

输入user pool 名称

配置属性

配置密码强度


创建手机端 clientId

  1. 创建测试用户
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
  1. 登录拿到 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 帮大家快速构建。

准备工作

  1. 创建存放证书 S3 桶

aws s3 mb s3://cconfig-certificate --region ap-southeast-1

  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
  1. 创建 dynamodb

3.1 创建 dynamodb table

3.2 配置索引

  1. Get IoT code endpoint

aws iot describe-endpoint --endpoint-type iot:Data-ATS --region ap-southeast-1

WorkFlow

  1. 用户在配网前已经登录平台
  2. 在用户请求时会带上token,平台通过token识别用户

部署服务

  1. Github clone Https://github.com/jianyew/CloudConfig_lambda_core.git,根据上面配置信息, 修改工程相关配置。
  2. 根据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

  1. apigetway endpoint

  1. 关键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

测试

  1. 下载证书

rootCA 下载:https://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/server-authentication.html

  1. 使用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()

  1. 查询用户的devices

本篇作者

汪建业

亚马逊云科技解决方案架构师,负责基于AWS云计算方案架构的咨询和设计,同时致力于 AWS IoT 和大数据服务在国内和全球企业客户的应用和推广。十余年分布式应用、大数据的分布式处理经验。