一、创建产品与设备
1.1 创建产品
进入OneNET平台(open.iot.10086.cn/console/sum…)后,点击「产品开发」,进入产品列表页面,「创建产品」- 智能化方式选择设备接入
1.2 设置物模型
「产品开发」- 「设置物模型」-「添加自定义功能点」或者是「导入物模型」
这里我添加好了2个属性power、temp和一个事件RolloverEvent
1.3 创建设备
进入OneNET平台后,展开菜单栏中的「设备接入与管理」,点击「设备管理」,进入设备列表页面。 点击「添加设备」,选中单个设备(默认方式),选择具体产品,完善设备基础信息,点击「确定」创建设备。
这里我创建了名为sheb1的设备
二、使用python代码生成密钥(token)
import base64
import hmac
from urllib.parse import quote
import time
# 中国移动官方文档给出的核心秘钥计算算法
def token(id,access_key):
version = '2018-10-31'
res = 'products/%s' % id # 通过产品ID访问产品API
# 用户自定义token过期时间
et = str(int(time.time()) + 63072000) # 设置为2年有效时间
# 签名方法,支持md5、sha1、sha256
method = 'sha1'
# 对access_key进行decode
key = base64.b64decode(access_key)
# 计算sign
org = et + '\n' + method + '\n' + res + '\n' + version
sign_b = hmac.new(key=key, msg=org.encode(), digestmod=method)
sign = base64.b64encode(sign_b.digest()).decode()
# value 部分进行url编码,method/res/version值较为简单无需编码
sign = quote(sign, safe='')
res = quote(res, safe='')
# token参数拼接
token = 'version=%s&res=%s&et=%s&method=%s&sign=%s' % (version, res, et, method, sign)
return token
username = "3BYy2V3T40" # 产品ID
accesskey = "KyUNtcnDVS1hK71BZY3b2VHztU9pm29Vj4EDCxvt9XU=" # accessKey
password = token(username, accesskey)
print(password)
注意修改参数username(产品ID)、accessKey(产品access_key) ,产品ID和access_key的获取如图
运行代码生成的token是这样
version=2018-10-31&res=products%2F3BYy2V3T40&et=1835680707&method=sha1&sign=ItaqzT%2BIms%2BBLcv%2FQawZ61%2B8qC8%3D
三、MQTT协议接入设备
准备下面代码运行需要的参数
- 产品ID
- 设备ID
- 设备密钥即第二步通过代码生成的token
3.1 设备连接
import paho.mqtt.client as mqtt
import json
import time
# OneNET MQTT服务器地址
MQTT_SERVER = "mqtts.heclouds.com"
# 产品ID
P_ID = "W4f1HLHAMz"
# 设备ID
DEVICE_ID = "sheb1"
# 设备密钥
DEVICE_KEY = "version=2018-10-31&res=products%2FW4f1HLHAMz&et=1835595227&method=sha1&sign=ZrBONND4VBN59Rt24tukA378nAM%3D"
client=None
def on_connect(client, userdata, flags, rc, properties):
print(f"Connected with result code {rc}")
# 连接成功后的操作,例如订阅主题,这里订阅了全部物模型相关主题
TOPIC = f"$sys/{P_ID}/{DEVICE_ID}/thing/#"
client.subscribe(TOPIC)
def on_message(client, userdata, msg):
print(f"Received message: {msg.topic} {msg.payload}")
def on_publish(client, userdata, result):
print("Message published")
def connect_mqtt():
global client
client = mqtt.Client(client_id=DEVICE_ID, protocol=mqtt.MQTTv311, callback_api_version=mqtt.CallbackAPIVersion.VERSION2)
client.username_pw_set(username=P_ID, password=DEVICE_KEY)
client.on_connect = on_connect
client.on_message = on_message
client.on_publish = on_publish
client.connect(MQTT_SERVER, 1883, 60)
client.loop_forever()
connect_mqtt()
验证结果,在OneNet平台可以看到设备已处于在线状态
3.2 平台下发数据-设备属性设置
import paho.mqtt.client as mqtt
import json
import time
# OneNET MQTT服务器地址
MQTT_SERVER = "mqtts.heclouds.com"
# 产品ID
P_ID = "W4f1HLHAMz"
# 设备ID
DEVICE_ID = "sheb1"
# 设备密钥
DEVICE_KEY = "version=2018-10-31&res=products%2FW4f1HLHAMz&et=1835595227&method=sha1&sign=ZrBONND4VBN59Rt24tukA378nAM%3D"
client=None
def on_connect(client, userdata, flags, rc, properties):
print(f"Connected with result code {rc}")
# 连接成功后的操作,例如订阅主题,这里订阅了全部物模型相关主题
TOPIC = f"$sys/{P_ID}/{DEVICE_ID}/thing/#"
client.subscribe(TOPIC)
def on_message(client, userdata, msg):
print(f"Received message: {msg.topic} {msg.payload}")
# 设备侧收到平台下发的数据
if msg.topic == f"$sys/{P_ID}/{DEVICE_ID}/thing/property/set":
data = json.loads(msg.payload)
print(data)
# 设备属性设置响应
TOPIC = f"$sys/{P_ID}/{DEVICE_ID}/thing/property/set_reply"
# 其中id需要与下发数据id一致,code为200代表成功,msg可以自定义
payload = {
"id": data['id'],
"code": 200,
"msg": "success"
}
client.publish(TOPIC, json.dumps(payload))
def on_publish(client, userdata, result):
print("Message published")
def connect_mqtt():
global client
client = mqtt.Client(client_id=DEVICE_ID, protocol=mqtt.MQTTv311, callback_api_version=mqtt.CallbackAPIVersion.VERSION2)
client.username_pw_set(username=P_ID, password=DEVICE_KEY)
client.on_connect = on_connect
client.on_message = on_message
client.on_publish = on_publish
client.connect(MQTT_SERVER, 1883, 60)
client.loop_forever()
connect_mqtt()
在设备管理详情页点击「设备调试」Tab栏,或进入产品开发-设备调试流程模块,选择「应用模拟器」,点击「启动调试」,可进行设置设备属性,topic: $sys/{pid}/{device-name}/thing/property/set_reply
可以看到已经收到属性设置
3.3 属性上报
import paho.mqtt.client as mqtt
import json
import time
# OneNET MQTT服务器地址
MQTT_SERVER = "mqtts.heclouds.com"
# 产品ID
P_ID = "W4f1HLHAMz"
# 设备ID
DEVICE_ID = "sheb1"
# 设备密钥
DEVICE_KEY = "version=2018-10-31&res=products%2FW4f1HLHAMz&et=1835595227&method=sha1&sign=ZrBONND4VBN59Rt24tukA378nAM%3D"
client=None
def on_connect(client, userdata, flags, rc, properties):
print(f"Connected with result code {rc}")
# 连接成功后的操作,例如订阅主题,这里订阅了全部物模型相关主题
TOPIC = f"$sys/{P_ID}/{DEVICE_ID}/thing/#"
client.subscribe(TOPIC)
def on_message(client, userdata, msg):
print(f"Received message: {msg.topic} {msg.payload}")
def on_publish(client, userdata, result):
print("Message published")
def connect_mqtt():
global client
client = mqtt.Client(client_id=DEVICE_ID, protocol=mqtt.MQTTv311, callback_api_version=mqtt.CallbackAPIVersion.VERSION2)
client.username_pw_set(username=P_ID, password=DEVICE_KEY)
client.on_connect = on_connect
client.on_message = on_message
client.on_publish = on_publish
client.connect(MQTT_SERVER, 1883, 60)
# 非阻塞启动循环
client.loop_start()
# 属性上报
def property_post():
# 主题(Topic)- 设备属性上报请求
TOPIC = f"$sys/{P_ID}/{DEVICE_ID}/thing/property/post"
timestamp = time.time()
# 发布消息
payload = {
"id": "123",
"version": "1.0",
"params": {
"power": { # power为产品物模型中定义的属性名称
"value": 55,
"time": timestamp
},
"temp": { # temp为产品物模型中定义的属性名称
"value": 55,
"time": timestamp
}
}
}
client.publish(TOPIC, json.dumps(payload))
connect_mqtt()
property_post()
client.loop_stop()
验证结果,在OneNet平台中可以看到属性已经上报成功
3.4 事件上报
import paho.mqtt.client as mqtt
import json
import time
# OneNET MQTT服务器地址
MQTT_SERVER = "mqtts.heclouds.com"
# 产品ID
P_ID = "W4f1HLHAMz"
# 设备ID
DEVICE_ID = "sheb1"
# 设备密钥
DEVICE_KEY = "version=2018-10-31&res=products%2FW4f1HLHAMz&et=1835595227&method=sha1&sign=ZrBONND4VBN59Rt24tukA378nAM%3D"
client=None
def on_connect(client, userdata, flags, rc, properties):
print(f"Connected with result code {rc}")
# 连接成功后的操作,例如订阅主题,这里订阅了全部物模型相关主题
TOPIC = f"$sys/{P_ID}/{DEVICE_ID}/thing/#"
client.subscribe(TOPIC)
def on_message(client, userdata, msg):
print(f"Received message: {msg.topic} {msg.payload}")
def on_publish(client, userdata, result):
print("Message published")
def connect_mqtt():
global client
client = mqtt.Client(client_id=DEVICE_ID, protocol=mqtt.MQTTv311, callback_api_version=mqtt.CallbackAPIVersion.VERSION2)
client.username_pw_set(username=P_ID, password=DEVICE_KEY)
client.on_connect = on_connect
client.on_message = on_message
client.on_publish = on_publish
client.connect(MQTT_SERVER, 1883, 60)
# 非阻塞启动循环
client.loop_start()
# 事件上报
def event_post():
# 主题(Topic)- 设备属性上报请求
TOPIC = f"$sys/{P_ID}/{DEVICE_ID}/thing/event/post"
timestamp = time.time()
# 发布消息
payload = {
"id": "123",
"version": "1.0",
"params": {
"RolloverEvent": { # RolloverEvent为产品物模型中定义的事件名称
"time":timestamp,
"value":{
"RolloverAccP":18, # 物模型中定义的事件输出参数
"RolloverAccE":19,
}
}
}
}
client.publish(TOPIC, json.dumps(payload))
connect_mqtt()
event_post()
client.loop_stop()
验证结果,在OneNet平台中可以看到事件已经上报成功
四、HTTP协议接入设备
注意HTTP协议接入需要在第一步「创建产品」的时候接入协议选择HTTP,其他创建产品和创建设备的步骤都一样,验证结果也一样,不再赘述,下面直接贴代码
4.1 设备上下线
import requests
import json
# OneNET MQTT服务器地址
MQTT_SERVER = "https://open.iot.10086.cn/fuse/http/"
# 产品ID
P_ID = "3BYy2V3T40"
# 设备ID
DEVICE_ID = "sheb2"
# 设备密钥
DEVICE_KEY = "version=2018-10-31&res=products%2F3BYy2V3T40&et=1835667958&method=sha1&sign=EDkn0Yk8NaVcFQZJlVZdEab98N0%3D"
hd = {
"Content-Type": "application/json",
"token": DEVICE_KEY
}
# 设备上下线
def on_connect():
data = {
'pid': P_ID,
'devName': DEVICE_ID,
'status': 1, # 1:上线 0:下线
"protocol":"HTTP",
"network": 0, # 联网方式,整数,上报卡标识或设备标识时必须,根据联网方式不同,校验以下卡标识和设备标识,取值**0-非蜂窝 1-移动 2-电信 3-联通 4-广电**
"sn": 'xxxxxxxxxxxx' # 设备序列号,模拟的时候可以随便填,但要注意规则:10-32个字符,只支持数字、大小写字母及“-”或“:”
}
page = requests.post(f'{MQTT_SERVER}device/online', headers=hd, json=data, verify=False).json()
print(page)
on_connect()
4.2 设备属性上报
import requests
import json
import time
# OneNET MQTT服务器地址
MQTT_SERVER = "https://open.iot.10086.cn/fuse/http/"
# 产品ID
P_ID = "3BYy2V3T40"
# 设备ID
DEVICE_ID = "sheb2"
# 设备密钥
DEVICE_KEY = "version=2018-10-31&res=products%2F3BYy2V3T40&et=1835667958&method=sha1&sign=EDkn0Yk8NaVcFQZJlVZdEab98N0%3D"
hd = {
"Content-Type": "application/json",
"token": DEVICE_KEY
}
# 设备属性上报
def property_post():
TOPIC = f"$sys/{P_ID}/{DEVICE_ID}/thing/property/post"
timestamp = time.time()
data = {
"id": "123",
"version": "1.0",
"params": {
"power": {
"value": 10,
"time": timestamp
},
"temp": {
"value": 11,
"time": timestamp
}
}
}
page = requests.post(f'{MQTT_SERVER}/device/thing/property/post?topic={TOPIC}&protocol=http', headers=hd, json=data, verify=False).json()
print(page)
property_post()
4.3 设备事件上报
import requests
import json
import time
# OneNET MQTT服务器地址
MQTT_SERVER = "https://open.iot.10086.cn/fuse/http/"
# 产品ID
P_ID = "3BYy2V3T40"
# 设备ID
DEVICE_ID = "sheb2"
# 设备密钥
DEVICE_KEY = "version=2018-10-31&res=products%2F3BYy2V3T40&et=1835667958&method=sha1&sign=EDkn0Yk8NaVcFQZJlVZdEab98N0%3D"
hd = {
"Content-Type": "application/json",
"token": DEVICE_KEY
}
# 设备事件上报
def event_post():
TOPIC = f"$sys/{P_ID}/{DEVICE_ID}/thing/event/post"
timestamp = time.time()
data = {
"id": "123",
"version": "1.0",
"params": {
"RolloverEvent": {
"time":timestamp,
"value":{
"power":99
}
}
}
}
page = requests.post(f'{MQTT_SERVER}/device/thing/event/post?topic={TOPIC}&protocol=http', headers=hd, json=data, verify=False).json()
print(page)
event_post()