Parcourir la source

Merge branch 'master' of https://github.com/RT-Thread-packages/micropython

armink il y a 7 ans
Parent
commit
05bf1450cf

+ 0 - 3
docs/09-Make_New_Module.md

@@ -1,3 +0,0 @@
-# RT-Thread MicroPython 创建新模块
-
-正在努力中,马上就来

+ 10 - 0
docs/09-Net_Programming_Guide/01-introduction.md

@@ -0,0 +1,10 @@
+# RT-Thread MicroPython 网络编程指南
+
+!!! abstract "简介"
+    MicroPython 提供丰富的网络功能,可以加快物联网项目的开发进程,本章介绍常用的网络功能以及相关模块的使用方法。了解网络功能之后,就可以将产品轻松的接入网络,实现更多物联网功能。
+
+## 预备知识
+
+- 在阅读本网络编程指南之前,需要先行了解 MicroPython 模块的[网络模块章节](../07-Network_Module/01-usocket.md) ,了解基本网络连接模块的使用方法。
+- 如果想要使用较为复杂的网络功能,需要在 menuconfig 中将工具模块中的模块都打开,并且必须开启网络模块中的  `usocket` 模块。
+

+ 31 - 0
docs/09-Net_Programming_Guide/02-HttpClient.md

@@ -0,0 +1,31 @@
+!!! abstract "简介"
+    本节介绍如何在 RT-Thread MicroPython 上使用 Http Client 功能,本章主要使用的模块为 `urequests` 。
+
+### 获取并安装 urequests 模块
+
+获取该模块有两种方式,详细操作可参考包管理章节:
+
+- 方法1:使用 upip 包管理工具下载,这里使用 `upip.install("micropython-urequests")` 命令,upip 工具将自动下载并安装  `urequests` 模块,下载过程如图所示:
+
+![1525690379859](../figures/install_urequests.png)
+
+- 方法2:从 MicroPython-lib 中复制到开发板上文件系统的 `/libs/mpy` 目录下。
+
+接下来 `urequests` 模块就可以被导入使用了。
+
+### urequests 模块的使用
+
+下面示例程序使用 `get` 命令来抓取 `http://www.baidu.com/` 的首页信息,并格式化输出:
+
+```python
+try:
+    import urequests as requests
+except ImportError:
+    import requests
+
+r = requests.get("http://www.baidu.com/")
+print(r)
+print(r.content)
+print(r.text)
+r.close()
+```

+ 49 - 0
docs/09-Net_Programming_Guide/03-HttpServer.md

@@ -0,0 +1,49 @@
+!!! abstract "简介"
+    本章介绍如何使用 RT-Thread MicroPython 搭建一个 Web 服务器,需要使用到的模块为 MicroWebSrv 模块。
+
+### 获取并安装 MicroWebSrv 模块 
+- 首先从 `https://github.com/jczic/MicroWebSrv.git` 将相关文件克隆到本地。
+- 将 `www` 文件夹拷贝到文件系统的根目录(这里将 SD 卡作为开发板文件系统的根目录)。
+
+![1525674983856](../figures/copy_www_dir.png)
+
+- 把其他文件拷贝到 /libs/mpy/ 文件夹中。
+
+![1525675205931](../figures/copy_webser_othres_dir.png)
+
+- 这样 MicroWebSrv 模块就安装好了,可以在 MicroPython 交互命令行中直接使用 `import` 命令导入了。
+
+### MicroWebSrv 模块的使用
+
+- 在 MSH 中,使用 ifconfig 命令查看开发板 IP 地址。
+- 输入 python 命令,进入 MicroPython 交互命令行。
+- 使用 import main 命令,启动 Web 服务器。
+
+![1525659036361](../figures/import_start.png)
+
+- 打开浏览器,在地址栏输入开发板 IP 地址并回车,即可看到 Web 页面。
+
+![1525659139123](../figures/open_web_page.png)
+
+- 输入网址 ip/test 使用表格填写示例。
+
+![1525659204069](../figures/use_test_func.png)
+
+如下代码完成了这个表格的获取功能:
+
+![1525770427295](../figures/get_test.png)
+
+- 点击 Submit,服务器返回你填写的信息。
+
+![1525659232565](../figures/use_submit.png)
+
+如下代码完成了数据的推送功能:
+
+![1525770467078](../figures/push_test.png)
+
+### 服务器功能的修改
+
+- 如果想过要通过服务器实现自己所需的功能,可以修改 main.py 文件,导入更多模块,使用 Python 语言来添加更多功能。
+- 在网页中展示加速度计和磁力计的例程中,下面的代码完成了这些数据的返回功能,可以参考 WebServer 的例子来对 main.py 进行修改,以达到自己想要完成的功能。
+
+![1525770559437](../figures/change_server_fuction.png)

+ 66 - 0
docs/09-Net_Programming_Guide/04-MQTT.md

@@ -0,0 +1,66 @@
+!!! abstract "简介"
+    MQTT 是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通讯协议 。本章介绍如何在 RT-Thread MicroPython 上使用 MQTT 功能,使用到的模块为 `umqtt.simple` 模块。
+
+### 获取并安装 umqtt.simple 模块
+同样的可以使用包管理中的两种方式来获取,使用 upip 安装的方式可使用  `upip.install("micropython-umqtt.simple")`如图:
+
+![1525690229174](../figures/install_umqtt_simple.png)
+
+### umqtt.simple 模块的使用
+####  MQTT 订阅功能
+- 使用 `iot.eclipse.org` 作为测试服务器
+```python
+import time
+from umqtt.simple import MQTTClient
+
+# Publish test messages e.g. with:
+# mosquitto_pub -t foo_topic -m hello
+
+# Received messages from subscriptions will be delivered to this callback
+def sub_cb(topic, msg):
+    print((topic, msg))
+
+def main(server="iot.eclipse.org"):   # 测试 server 为 iot.eclipse.org
+    c = MQTTClient("RT-Thread", server)
+    c.set_callback(sub_cb)
+    c.connect()
+    c.subscribe(b"foo_topic")         # 订阅 foo_topic 主题
+    while True:
+        if True:
+            # Blocking wait for message
+            c.wait_msg()
+        else:
+            # Non-blocking wait for message
+            c.check_msg()
+            # Then need to sleep to avoid 100% CPU usage (in a real
+            # app other useful actions would be performed instead)
+            time.sleep(1)
+
+    c.disconnect()
+
+if __name__ == "__main__":
+    main()
+```
+
+- 使用 python 命令执行上述代码文件,就会连接上 MQTT 服务器,可收到我们从另一个客户端发布的以 `foo_topic`为主题的内容
+
+![1525665942426](../figures/sub_topic.png)
+
+####  MQTT 发布功能
+- 执行下面的代码后将向 MQTT 服务器发布以 `foo_topic` 为主题的信息
+```python
+from umqtt.simple import MQTTClient
+
+# Test reception e.g. with:
+# mosquitto_sub -t foo_topic
+
+def main(server="iot.eclipse.org"):
+    c = MQTTClient("SummerGift", server)
+    c.connect()
+    c.publish(b"foo_topic", b"Hello RT-Thread !!!")
+    c.disconnect()
+
+if __name__ == "__main__":
+    main()
+
+```

+ 202 - 0
docs/09-Net_Programming_Guide/05-Cloud-OneNET.md

@@ -0,0 +1,202 @@
+!!! abstract "简介"
+    本节介绍如何使用 RT-Thread MicroPython 来将设备接入 OneNET 云平台,本次示例使用的接入协议为 MQTT。
+
+## 准备工作
+
+- 首先需要安装 `urequests`  模块和 `umqtt.simple` 模块,安装方法参考 [HttpClient ](./02-HttpClient.md) 和 [MQTT ](./04-MQTT.md) 章节。
+- 本章实例代码在最后一节的附录中,可以在添加必要的注册信息后复制到 main.py 文件中在 MSH 中使用 python 命令来执行。
+
+## 产品创建
+
+- 想要将开发板接入 OneNET 云平台,首先要进行产品的创建,创建分为两步,第一步是注册一个用户账号,第二步是创建一个基于特定协议的产品。
+
+### 用户注册
+
+- 为了使用 OneNET 设备云的强大功能,首先要在 OneNET 上[注册开发者账号](https://open.iot.10086.cn/doc/art436.html#104),来创建专属的“开发者中心 。
+
+### 产品创建
+
+- 接下来需要在 OneNET 平台上[创建产品](https://open.iot.10086.cn/doc/art437.html#104)。这里要注意的是在最后选择`设备接入方式`和`设备接入协议时`,因为本次示例使用的是 MQTT 协议,所以要在设备接入方式中选择`公开协议`,设备接入协议选择 `MQTT`。
+
+![1525764833130](../figures/choose_mqtt.png)
+
+## 硬件接入
+
+本章节将介绍如何将设备接入到 OneNET 云平台上。并且演示一个云平台向设备发送命令,设备向云平台返回命令发送次数的示例。
+
+### 设备的注册和接入
+
+- 成功创建设备之后,将得到的产品 ID 记录下来供后面推送数据使用。
+
+![1525765493792](../figures/get_product_id.png)
+
+- 将设备的`正式环境注册码`记录下来用于注册新的设备。
+
+![1525765209683](../figures/reg_code.png)
+
+- 接下来打开例程中的 main.py,修改 sn 为设备唯一标识码,product_id 为上面得到的6位产品 ID,regKey 为上面记录下来的正式环境注册码。
+
+![1525766961043](../figures/change_code.png)
+
+- 在开发板中运行 main.py 即可在 OneNET 上看到我们注册的设备。
+
+![1525767092149](../figures/run_main.png)
+
+- 名为 `DeviceRT_Thread_Test_Product` 的设备已经注册完毕并且上线。
+
+![1525767167244](../figures/reg_done.png)
+
+### 云平台向设备发送命令
+
+- 可以通过发送命令功能来给开发板发送几组命令。
+
+![1525767264155](../figures/cmd1.png)
+
+![1525767369050](../figures/cmd2.png)
+
+- 可以在设备端看到云平台下发的数据,同时设备端会上传命令发送次数的数据
+
+![1525767520609](../figures/cmd3.png)
+
+### 设备向云平台上传数据
+
+- 点击数据流管理功能来查看设备端上传的数据
+
+![1525767621708](../figures/look_data.png)
+
+- 可以在数据流管理中看到设备端上传的的命令发送次数 switch
+
+![1525767740215](../figures/switch.png)
+
+- 这里的 switch 数据是在 mqtt.py 的 pubData 函数里面修改的,可以通过 value 对象的内容来给云平台上传不同的数据。
+
+![1525774755758](../figures/change_pub.png)
+
+- 至此设备和 OneNET 云平台就对接好了。
+
+### 添加独立应用
+
+- 为了方便使用还可以给设备[添加独立的应用](https://open.iot.10086.cn/doc/art461.html#108),效果如下图:
+
+![1525768143233](../figures/add_app.png)
+
+## 代码讲解
+
+- 通过修改 value 对象来修改向服务器发送的数据,这里是发送到特殊的系统 topic `$dp`
+
+![1525774792209](../figures/code_review1.png)
+
+- 给服务器发送数据的触发条件是收到服务器下发的命令,这样就没有保证会一直有数据发送到服务器,所以在没有数据交换的一段时间后,MQTT 连接有可能断开。
+
+![1525768433046](../figures/code_review2.png)
+
+### 附录示例代码
+
+```python
+import urequests as requests
+from umqtt.simple import MQTTClient
+import ujson as json
+import time
+
+class Register():
+    def __init__(self, url='', title='', sn='', mac=''):
+        self.url = url
+        self.title = title
+        self.sn = sn
+        self.mac = mac
+        self.sock = None
+        self.tjson = {}
+        self.erron = 0
+        self.key = ''
+        self.device_id = ''
+
+    def regist(self):
+        assert self.url is not None, "Url is not set"
+        _, _, host, path = self.url.split('/', 3)
+        if host == '':
+            return
+        device = {"mac":self.mac} if self.sn == '' else {"sn":self.sn}
+        if self.title != '':
+            device['title'] = self.title
+        jdata = json.dumps(device)
+
+        resp = requests.post(self.url, data=jdata)
+        if resp:
+            self.tjson = resp.json()
+            if self.tjson['errno'] == 0:
+                self.key = self.tjson['data']['key']
+                self.device_id = self.tjson['data']['device_id']
+            return 0
+        else:
+            return -1
+
+class OneNetMqtt:
+    failed_count = 0
+
+    def __init__(self, client_id='', username='', password=''):
+        self.server = "183.230.40.39"
+        self.client_id = client_id
+        self.username = username
+        self.password = password
+        self.topic = "topic_sub"               # 填入测试 topic
+        self.mqttClient = MQTTClient(self.client_id, self.server,6002,self.username,self.password)
+        self.cmd_times = 0                      # publish count
+
+    def pubData(self, t):
+        value = {'datastreams':[{"id":"switch","datapoints":[{"value": self.cmd_times }]}]}
+        jdata = json.dumps(value)
+        jlen = len(jdata)
+        bdata = bytearray(jlen+3)
+        bdata[0] = 1                             # publish data in type of json
+        bdata[1] = int(jlen / 256)               # data lenght
+        bdata[2] = jlen % 256                    # data lenght
+        bdata[3:jlen+4] = jdata.encode('ascii')  # json data
+        print('publish data', str(self.cmd_times + 1))
+        try:
+            self.mqttClient.publish('$dp', bdata)  # $dp 为特殊系统 topic,可以通过这个 topic 给系统推送信息,但是不能订阅这个 topic
+            self.cmd_times += 1
+            self.failed_count = 0
+        except Exception as ex:
+            self.failed_count += 1
+            print('publish failed:', ex.message())
+            if self.failed_count >= 3:
+                print('publish failed three times, esp resetting...')
+                reset()
+
+    def sub_callback(self, topic, msg):
+        print((topic,msg))
+        cmd = msg.decode('ascii').split(" ")
+        print('sub_callback')
+
+    def connect(self):
+        self.mqttClient.set_callback(self.sub_callback)
+        self.mqttClient.connect()
+        self.mqttClient.subscribe(self.topic)
+        print("Connected to %s, subscribed to %s topic." % (self.server, self.topic))
+        try:
+            while True:
+                self.mqttClient.check_msg()
+                print("pubdata")
+                self.pubData('x')
+
+        finally:
+            self.mqttClient.disconnect()
+            print('MQTT closed')
+
+def main():
+    sn = 'RT_Thread_Test_Product'           #1、填入设备唯一标识符
+    title = 'Device' + sn 
+    product_id = 'XXXXX'                   #2、填入创建设备时获得的产品 ID
+    regKey = 'XXXXXXXX'                    #3、填入正式环境注册码
+    url = 'http://api.heclouds.com/register_de?register_code=' + regKey
+
+    reg = Register(url=url, title=title, sn=sn)      #根据上面的信息注册设备,如果已经注册不再重复注册
+    if reg.regist()==0:
+        MQTT = OneNetMqtt(client_id=reg.device_id, username=product_id, password=reg.key) #开启 MQTT 服务
+        MQTT.connect()
+    else:
+        print('Error: No Client ID!')
+
+if __name__ == "__main__":
+    main()
+```

+ 0 - 3
docs/10-Net_Programming_Guide.md

@@ -1,3 +0,0 @@
-# RT-Thread MicroPython 网络编程指南
-
-正在努力中,马上就来

BIN
docs/figures/add_app.png


BIN
docs/figures/change_code.png


BIN
docs/figures/change_pub.png


BIN
docs/figures/change_server_fuction.png


BIN
docs/figures/choose_mqtt.png


BIN
docs/figures/cmd1.png


BIN
docs/figures/cmd2.png


BIN
docs/figures/cmd3.png


BIN
docs/figures/code_review1.png


BIN
docs/figures/code_review2.png


BIN
docs/figures/copy_webser_othres_dir.png


BIN
docs/figures/copy_www_dir.png


BIN
docs/figures/get_product_id.png


BIN
docs/figures/get_test.png


BIN
docs/figures/import_start.png


BIN
docs/figures/install_umqtt_simple.png


BIN
docs/figures/install_urequests.png


BIN
docs/figures/look_data.png


BIN
docs/figures/open_web_page.png


BIN
docs/figures/push_test.png


BIN
docs/figures/reg_code.png


BIN
docs/figures/reg_done.png


BIN
docs/figures/run_main.png


BIN
docs/figures/sub_topic.png


BIN
docs/figures/switch.png


BIN
docs/figures/use_submit.png


BIN
docs/figures/use_test_func.png