diff --git a/docs/Advanced_development/zh/QuecPythonCloud/OneNET_MQTT.md b/docs/Advanced_development/zh/QuecPythonCloud/OneNET_MQTT.md new file mode 100644 index 0000000000000000000000000000000000000000..dca40bde8d4ae2886bd4ad2115efc83bd1a50305 --- /dev/null +++ b/docs/Advanced_development/zh/QuecPythonCloud/OneNET_MQTT.md @@ -0,0 +1,314 @@ +## 文档历史 + +**修订记录** + +| **版本** | **日期** | **作者** | **变更表述** | +| -------- | ---------- | -------- | ------------ | +| 1.0 | 2021-11-16 | Chic | 初始版本 | + + + +# QuecPython 接入OneNET_MQTT + +文档主要介绍如何使用“MQTT物联网套件”,MQTT物联网套件为开发者提供高效、稳定、安全的设备接入服务,具有海量接入、数据存储、设备管理、设备直接命令、设备状态同步、消息分发等功能,支持用户通过规则引擎对接OneNET增值服务,灵活地实现服务的扩展。 + + + +## 云端设置 + +移动云首页:[https://open.iot.10086.cn](https://www.aliyun.com) + +### 进入平台 + +点击【产品服务】---【MQTT物联网套件】 + +![OneNET_MQTT_01](media\OneNET_MQTT_01.png) + + + +### 添加产品 + +![OneNET_MQTT_02](media\OneNET_MQTT_02.png) + +![OneNET_MQTT_03](media\OneNET_MQTT_03.png) + +![OneNET_MQTT_04](media\OneNET_MQTT_04.png) + +### 添加设备 + +点击“Chic_演示产品”进入产品概况 + +![OneNET_MQTT_05](media\OneNET_MQTT_05.png) + +左侧栏目点击【设备列表】,再点击右边的“添加设备” + +![OneNET_MQTT_06](media\OneNET_MQTT_06.png) + +设置设备名称: + +![OneNET_MQTT_07](media\OneNET_MQTT_07.png) + +添加后,设备列表显示所有设备 + +![OneNET_MQTT_08](media\OneNET_MQTT_08.png) + +### 获取设备信息 + +“设备名称”、“access_key”、“产品ID”三个参数用于下个步骤生成连接Password; + +在“设备列表”中的设备,点击“详情” + +![OneNET_MQTT_09](media\OneNET_MQTT_09.png) + +可以看到“设备名称”、“access_key” + +![OneNET_MQTT_10](media\OneNET_MQTT_10.png) + +在“产品”中的设备,点击“详情” + +左侧栏目点击【产品概况】可看到“产品ID” + +![OneNET_MQTT_11](media\OneNET_MQTT_11.png) + +### 生成Password + +直接使用官方提供Python语言的token算法生成Password + +[https://open.iot.10086.cn/doc/mqtt/book/manual/auth/python.html](http://docs-aliyun.cn-hangzhou.oss.aliyun-inc.com/assets/attach/189223/cn_zh/1605168543507/MQTT_Password.7z?spm=a2c4g.11186623.2.19.373573a8XfigN5&file=MQTT_Password.7z) + +token分两种:一型一密、一机一密 + +```python +import base64 +import hmac +import time +from urllib.parse import quote + +# 场景 res参数格式 示例 说明 +# API访问 products/{pid} products/123123 +# 设备连接 products/{pid}/devices/{device_name} products/123123/devices/mydev 需使用设备级密钥 +product = 0 +device = 1 +TYPE = device +# TYPE 用于选择一型一密,还是一机一密 + +def token(id, access_key, deviceName=None): + global product + global device + global TYPE + + version = '2018-10-31' + + if TYPE == product: + res = 'products/%s' % id # 通过产品ID访问产品API + elif TYPE == device: + res = ('products/%s/devices/%s' % (id, deviceName)) + + # 用户自定义token过期时间 + et = str(int(time.time()) + 36000000) + + # 签名方法,支持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 + + +if __name__ == '__main__': + # MQTT + id = '469948' # 产品ID + if TYPE == product: + access_key = 'kKsubaG7FzMgzR6N3eUD53319Qu+K4MCvw6KzOYc5eI=' # 产品access_key + elif TYPE == device: + access_key = 'rs2FaE5BuygJZkWKDA5okKt1RFpwOx53hbu6hwyCS4U=' # 设备access_key + deviceName = 'Chic_D' + print(token(id, access_key, deviceName)) +``` + +### mqttfx连接平台 + +[开发指南_开发者文档_OneNET (10086.cn)](https://open.iot.10086.cn/doc/mqtt/book/device-develop/manual.html) + +获取平台服务器IP地址、端口: + +![OneNET_MQTT_12](media\OneNET_MQTT_12.png) + +![OneNET_MQTT_13](media\OneNET_MQTT_13.png) + +连接成功! + +![OneNET_MQTT_14](media\OneNET_MQTT_14.png) + +### 上报和下发数据 + +[上传数据点_开发者文档_OneNET (10086.cn)](https://open.iot.10086.cn/doc/mqtt/book/example/datapoints.html) + +topic 命名规则如下: + +$sys/{pid}/{device-name}/dp/post/json/+ + +本例中,订阅topic为: + +`$sys/469948/Chic_D/dp/post/json/+` + +点击Subscribe,完成topic订阅 + +![OneNET_MQTT_15](media\OneNET_MQTT_15.png) + +topic 命名规则如下: + +$sys/{pid}/{device-name}/dp/post/json + +本例中,发布 topic 名称为: + +`$sys/469948/Chic_D/dp/post/json` + +payload示例如下: + +```json +{ + "id": 123, + "dp": { + "temperatrue": [{ + "v": 30, + }], + "power": [{ + "v": 4.5, + }] + } +} +``` + +![OneNET_MQTT_16](media\OneNET_MQTT_16.png) + +点击Publish,发布消息,已订阅的设备立即收到消息 + +![OneNET_MQTT_17](media\OneNET_MQTT_17.png) + + + +## 软件设计 + +示例代码: + +```python +from umqtt import MQTTClient + +# 连接协议 证书 地址 端口 说明 +# MQTT 证书下载 mqttstls.heclouds.com 8883 加密接口 +# MQTT - mqtts.heclouds.com 1883 非加密接口 + +# 参数 是否必须 参数说明 +# clientId 是 设备名称 +# username 是 平台分配的产品ID +# password 是 填写经过 key 计算的 token + +SERVER = b'mqtts.heclouds.com' +PORT = 1883 +CLIENT_ID = b'Chic_D' +USER = b'469948' +PASSWORD = b'version=2018-10-31&res=products%2F469948%2Fdevices%2FChic_D&et=1673053248&method=sha1&sign=prIMDQ23WFI6PMj2IWpaRJJL4eE%3D' + +IMEI = None # modem.getDevImei() +SUB_TOPIC = '$sys/469948/Chic_D/dp/post/json/+' +PUB_TOPIC = '$sys/469948/Chic_D/dp/post/json' + +def GetDevImei(): + global IMEI + # IMEI = modem.getDevImei() + IMEI = '001' + print(IMEI) + +state = 0 + +def sub_cb(topic, msg): + global state + print( + "Subscribe Recv: Topic={},Msg={}".format( + topic.decode(), + msg.decode())) + state = 1 + + +def MQTT_Init(): + # 创建一个mqtt实例 + c = MQTTClient( + client_id=CLIENT_ID, + server=SERVER, + port=PORT, + user=USER, + password=PASSWORD, + keepalive=30) # 必须要 keepalive=30 ,否则连接不上 + # 设置消息回调 + c.set_callback(sub_cb) + # 建立连接 + try: + c.connect() # c.connect(clean_session=True) + except Exception as e: + print('!!!,e=%s' % e) + return + print('connected') + + # 订阅主题 + c.subscribe(SUB_TOPIC.format(IMEI)) + # 发布消息 + Payload = ''' + { + "id": 123, + "dp": { + "temperatrue": [{ + "v": 30, + }], + "power": [{ + "v": 4.5, + }] + } + }''' + c.publish(PUB_TOPIC.format(IMEI), Payload) + + while True: + c.wait_msg() + if state == 1: + break + + # 关闭连接 + c.disconnect() + + +def main(): + # GetDevImei() + MQTT_Init() + + +if __name__ == "__main__": + main() +``` + +接下来就可以下载验证了,python代码不需要编译,直接通过QPYcom工具把.py文件下载到模块中运行。 + +## 下载验证 + +下载.py文件到模组运行: + +![OneNET_MQTT_18](media\OneNET_MQTT_18.png) + +下载之后,手动让脚本运行起来。 + +![OneNET_MQTT_19](media\OneNET_MQTT_19.png) + +## 配套代码 diff --git a/docs/Advanced_development/zh/QuecPythonCloud/code/OneNET_MQTT.py b/docs/Advanced_development/zh/QuecPythonCloud/code/OneNET_MQTT.py new file mode 100644 index 0000000000000000000000000000000000000000..4fb122f51d7d1a3c41dbcc27a284a8a2f68d3744 --- /dev/null +++ b/docs/Advanced_development/zh/QuecPythonCloud/code/OneNET_MQTT.py @@ -0,0 +1,90 @@ +from umqtt import MQTTClient + +# 连接协议 证书 地址 端口 说明 +# MQTT 证书下载 mqttstls.heclouds.com 8883 加密接口 +# MQTT - mqtts.heclouds.com 1883 非加密接口 + +# 参数 是否必须 参数说明 +# clientId 是 设备名称 +# username 是 平台分配的产品ID +# password 是 填写经过 key 计算的 token + +SERVER = b'mqtts.heclouds.com' +PORT = 1883 +CLIENT_ID = b'Chic_D' +USER = b'469948' +PASSWORD = b'version=2018-10-31&res=products%2F469948%2Fdevices%2FChic_D&et=1673053248&method=sha1&sign=prIMDQ23WFI6PMj2IWpaRJJL4eE%3D' + +IMEI = None # modem.getDevImei() +SUB_TOPIC = '$sys/469948/Chic_D/dp/post/json/+' +PUB_TOPIC = '$sys/469948/Chic_D/dp/post/json' + +def GetDevImei(): + global IMEI + # IMEI = modem.getDevImei() + IMEI = '001' + print(IMEI) + +state = 0 + +def sub_cb(topic, msg): + global state + print( + "Subscribe Recv: Topic={},Msg={}".format( + topic.decode(), + msg.decode())) + state = 1 + + +def MQTT_Init(): + # 创建一个mqtt实例 + c = MQTTClient( + client_id=CLIENT_ID, + server=SERVER, + port=PORT, + user=USER, + password=PASSWORD, + keepalive=30) # 必须要 keepalive=30 ,否则连接不上 + # 设置消息回调 + c.set_callback(sub_cb) + # 建立连接 + try: + c.connect() # c.connect(clean_session=True) + except Exception as e: + print('!!!,e=%s' % e) + return + print('connected') + + # 订阅主题 + c.subscribe(SUB_TOPIC.format(IMEI)) + # 发布消息 + Payload = ''' + { + "id": 123, + "dp": { + "temperatrue": [{ + "v": 30, + }], + "power": [{ + "v": 4.5, + }] + } + }''' + c.publish(PUB_TOPIC.format(IMEI), Payload) + + while True: + c.wait_msg() + if state == 1: + break + + # 关闭连接 + c.disconnect() + + +def main(): + # GetDevImei() + MQTT_Init() + + +if __name__ == "__main__": + main() diff --git a/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_01.png b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_01.png new file mode 100644 index 0000000000000000000000000000000000000000..e7ba8892c78db9a89519f80566d4f157344bf8d4 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_01.png differ diff --git a/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_02.png b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_02.png new file mode 100644 index 0000000000000000000000000000000000000000..06f75ed6fb32352dc3557e1d1664e8b2275cf6e9 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_02.png differ diff --git a/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_03.png b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_03.png new file mode 100644 index 0000000000000000000000000000000000000000..f8b1f43a180f71a7649cc76d12391ac320c05497 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_03.png differ diff --git a/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_04.png b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_04.png new file mode 100644 index 0000000000000000000000000000000000000000..6fb984997db07f9b3f20656e920a856d6100dc0d Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_04.png differ diff --git a/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_05.png b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_05.png new file mode 100644 index 0000000000000000000000000000000000000000..37ba008eb16fd6f835308bc7fdb732f1b76cffc3 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_05.png differ diff --git a/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_06.png b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_06.png new file mode 100644 index 0000000000000000000000000000000000000000..639b9f4cbe447ec44ba928e29084c1cd4316de15 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_06.png differ diff --git a/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_07.png b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_07.png new file mode 100644 index 0000000000000000000000000000000000000000..b086023093e5bdcb7ff73269baf414ad06836c9b Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_07.png differ diff --git a/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_08.png b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_08.png new file mode 100644 index 0000000000000000000000000000000000000000..000a479abfe04730f2d8ba92314abb877144e045 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_08.png differ diff --git a/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_09.png b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_09.png new file mode 100644 index 0000000000000000000000000000000000000000..d545fb0c1f91dc168033d54579449e7e558db86a Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_09.png differ diff --git a/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_10.png b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_10.png new file mode 100644 index 0000000000000000000000000000000000000000..b6cf66a045956ea77d27753693cb8af8a4c61d1e Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_10.png differ diff --git a/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_11.png b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_11.png new file mode 100644 index 0000000000000000000000000000000000000000..cec419eb15053357f998d72b768a92930a78e9b8 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_11.png differ diff --git a/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_12.png b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_12.png new file mode 100644 index 0000000000000000000000000000000000000000..7bfed2850ce29e8c13eeef80046f994e6a50ddc7 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_12.png differ diff --git a/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_13.png b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_13.png new file mode 100644 index 0000000000000000000000000000000000000000..49231af718b67e50e8c1c252ca66d88974592ce3 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_13.png differ diff --git a/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_14.png b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_14.png new file mode 100644 index 0000000000000000000000000000000000000000..72c0aaf5725d1b8ecdf1a618b493521022a71780 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_14.png differ diff --git a/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_15.png b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_15.png new file mode 100644 index 0000000000000000000000000000000000000000..e4f17e9cecc2209610699faf53e69b259ff025c2 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_15.png differ diff --git a/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_16.png b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_16.png new file mode 100644 index 0000000000000000000000000000000000000000..692a89f93c517a1f8d78018d50e9b5e87f7cf453 Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_16.png differ diff --git a/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_17.png b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_17.png new file mode 100644 index 0000000000000000000000000000000000000000..a1a6a93c2e9457af9cfb7faef4cca9ba4a43628f Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_17.png differ diff --git a/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_18.png b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_18.png new file mode 100644 index 0000000000000000000000000000000000000000..8224fa566b38f184ae79626319ad51c81d2d666d Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_18.png differ diff --git a/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_19.png b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_19.png new file mode 100644 index 0000000000000000000000000000000000000000..e6b536331c211e65e08f780ededf3c5676cebdfb Binary files /dev/null and b/docs/Advanced_development/zh/QuecPythonCloud/media/OneNET_MQTT_19.png differ diff --git a/docs/Advanced_development/zh/sidebar.yaml b/docs/Advanced_development/zh/sidebar.yaml index f12bff6a0f7a3b07d753d7e376ac0bf34145bb5c..85d6a2e052ecf97573d43ea435b170199faae90d 100644 --- a/docs/Advanced_development/zh/sidebar.yaml +++ b/docs/Advanced_development/zh/sidebar.yaml @@ -11,6 +11,8 @@ items: file: QuecPythonCloud/HuaweiCloud.md - label: 接入亚马逊云 file: QuecPythonCloud/AmazonCloud.md + - label: 接入移动云 + file: QuecPythonCloud/OneNET_MQTT.md - label: 基础外设 items: - label: LCD开发