阿里云物联网平台体验(树莓派+Python篇)
虽然对阿里云物联网平台比较熟悉了,从一开始就有幸参与了飞凤平台(Link Develop 一站式开发平台的前身)的一些偏硬件接入的工作。但是同时也见证了阿里云物联网团队从几十人到数百人的迅速扩张,其物联网平台所承载的内容也急速膨胀,物联网开发套件基础版、飞凤、Link Develop一站式开发平台、物联网开发平台高级版、飞燕、飞象、城市大脑、农业大脑和工业互联平台不一而足……,很难有精力真正熟悉和了解阿里云的每一款物联网产品。
这次有幸成为物联网平台的阿里云MVP体验官,可以从另外一个角度来体验阿里云物联网平台了。最早我们都是基于MCU单片+.NET MF平台,直接采用MQTT协议实现相关的代码对接阿里云平台,虽然也可以基于组态配置很灵活地接入物联网平台,但是对一些WEB、AI和云端开发的人来说还是有些陌生。正是因为这些需求,JS,Java,Python这些高级语言已经走入了硬件开发,可以直接在MCU芯片上运行,大大提速了物联网云和端的连接工作。
本篇文章就是采用高级语言Python基于树莓派进行物联网云端对接的(后续篇幅会介绍nodejs的云端对接)。
下面是阿里云团队快递过来的相关测试硬件:
1、 树莓派3B+ 自带wifi和蓝牙
2、 DHT11温湿度模块
3、 LED灯模块
第一步:我们需要为树莓派安装操作系统
我们安装的是Raspbian固件,可以按如下链接介绍的步骤进行安装:https://www.yuque.com/cloud-dev/iot-tech/ig269q
第二步:安装阿里云平台的Python SDK
执行如下指令:$ pip install aliyun-python-sdk-iot-client
第三步:代码编写
在阿里云平台的说明文档:https://www.yuque.com/cloud-dev/iot-tech/rz6fpl 中已经提供了一个示例代码,不过功能相对简单,就是把两个随机数送到云端。
我们设计一个相对复杂的场景,我们首先要实现双向通信,不仅仅把传感器数据送到云端,我们还要让云端下发一个指令,控制相关的设备。
上传数据我们选择一个真实的传感器 DHT11,可以获取温度和湿度值。另外还有一个LED灯模块,通过云端下达的指令,控制灯亮和灯灭。
树莓派的管脚定义图如下:
DHT11模块共3根线,属于单总线通信,电源线我们接入5V-4pin,地线我们接入GND-6pin,通信pin我们接入GPIO16-36pin。LED模块也是3根线,我们电源线接入3V3-1pin,地线接入GND-9pin,控制线接入GPIO4-7pin。
LED的控制相对容易,就是控制管脚的高低电平即可。
led_pin = 4 //GPIO为4
GPIO.setmode(GPIO.BCM) //BCM的GPIO定义
GPIO.setup(led_pin, GPIO.OUT) //设置为输出模式
点亮灯:
<span style="color:#f8f8f2"><code class="language-c">GPIO<span style="color:#f8f8f2">.</span><span style="color:#e6db74">output</span><span style="color:#f8f8f2">(</span>led_pin<span style="color:#f8f8f2">,</span> GPIO<span style="color:#f8f8f2">.</span>HIGH<span style="color:#f8f8f2">)</span></code></span>
<span style="color:#f8f8f2"><code class="language-c">GPIO<span style="color:#f8f8f2">.</span><span style="color:#e6db74">output</span><span style="color:#f8f8f2">(</span>led_pin<span style="color:#f8f8f2">,</span> GPIO<span style="color:#f8f8f2">.</span>LOW<span style="color:#f8f8f2">)</span></code></span>
DHT11相对比较复杂,我2010年曾经写过一篇博文。
由于代码比较多,所以我们封装为一个函数,并且可以同时返回两个值,一个是温度T,一个是湿度H。
网上大部分Python的实例都是读一次温湿度的,如果要连续读,必须间隔3秒左右,否则很容易失败。由于linux不是实时系统,我们发现即使间隔3秒,无法正确获取温湿度值的现象也时有发生,并且有时候居然也有通过校验的错误值出现。
DHT11的数据Pin接入的是 GPIO16,所以我们定义pin的代码如下:
dht_pin =16
封装函数的代码如下:
<span style="color:#f8f8f2"><code class="language-c">def <span style="color:#e6db74"><span style="color:#a6e22e">GetDTH</span></span><span style="color:#f8f8f2"><span style="color:#f8f8f2">(</span></span><span style="color:#f8f8f2"><span style="color:#f8f8f2">)</span></span><span style="color:#f8f8f2">:</span> data <span style="color:#f8f8f2">=</span> <span style="color:#f8f8f2">[</span><span style="color:#f8f8f2">]</span>j <span style="color:#f8f8f2">=</span> <span style="color:#ae81ff"><span style="color:#ae81ff">0</span></span> GPIO<span style="color:#f8f8f2">.</span><span style="color:#e6db74">setup</span><span style="color:#f8f8f2">(</span>dht_pin<span style="color:#f8f8f2">,</span> GPIO<span style="color:#f8f8f2">.</span>OUT<span style="color:#f8f8f2">)</span>GPIO<span style="color:#f8f8f2">.</span><span style="color:#e6db74">output</span><span style="color:#f8f8f2">(</span>dht_pin<span style="color:#f8f8f2">,</span> GPIO<span style="color:#f8f8f2">.</span>LOW<span style="color:#f8f8f2">)</span>time<span style="color:#f8f8f2">.</span><span style="color:#e6db74">sleep</span><span style="color:#f8f8f2">(</span><span style="color:#ae81ff"><span style="color:#ae81ff">0.02</span></span><span style="color:#f8f8f2">)</span>GPIO<span style="color:#f8f8f2">.</span><span style="color:#e6db74">output</span><span style="color:#f8f8f2">(</span>dht_pin<span style="color:#f8f8f2">,</span> GPIO<span style="color:#f8f8f2">.</span>HIGH<span style="color:#f8f8f2">)</span>GPIO<span style="color:#f8f8f2">.</span><span style="color:#e6db74">setup</span><span style="color:#f8f8f2">(</span>dht_pin<span style="color:#f8f8f2">,</span> GPIO<span style="color:#f8f8f2">.</span>IN<span style="color:#f8f8f2">)</span><span style="color:#66d9ef"><span style="color:#f92672">while</span></span> GPIO<span style="color:#f8f8f2">.</span><span style="color:#e6db74">input</span><span style="color:#f8f8f2">(</span>dht_pin<span style="color:#f8f8f2">)</span> <span style="color:#f8f8f2">==</span> GPIO<span style="color:#f8f8f2">.</span>LOW<span style="color:#f8f8f2">:</span><span style="color:#66d9ef"><span style="color:#f92672">continue</span></span><span style="color:#66d9ef"><span style="color:#f92672">while</span></span> GPIO<span style="color:#f8f8f2">.</span><span style="color:#e6db74">input</span><span style="color:#f8f8f2">(</span>dht_pin<span style="color:#f8f8f2">)</span> <span style="color:#f8f8f2">==</span> GPIO<span style="color:#f8f8f2">.</span>HIGH<span style="color:#f8f8f2">:</span><span style="color:#66d9ef"><span style="color:#f92672">continue</span></span><span style="color:#66d9ef"><span style="color:#f92672">while</span></span> j <span style="color:#f8f8f2"><</span> <span style="color:#ae81ff"><span style="color:#ae81ff">40</span></span><span style="color:#f8f8f2">:</span>k <span style="color:#f8f8f2">=</span> <span style="color:#ae81ff"><span style="color:#ae81ff">0</span></span><span style="color:#66d9ef"><span style="color:#f92672">while</span></span> GPIO<span style="color:#f8f8f2">.</span><span style="color:#e6db74">input</span><span style="color:#f8f8f2">(</span>dht_pin<span style="color:#f8f8f2">)</span> <span style="color:#f8f8f2">==</span> GPIO<span style="color:#f8f8f2">.</span>LOW<span style="color:#f8f8f2">:</span><span style="color:#66d9ef"><span style="color:#f92672">continue</span></span><span style="color:#66d9ef"><span style="color:#f92672">while</span></span> GPIO<span style="color:#f8f8f2">.</span><span style="color:#e6db74">input</span><span style="color:#f8f8f2">(</span>dht_pin<span style="color:#f8f8f2">)</span> <span style="color:#f8f8f2">==</span> GPIO<span style="color:#f8f8f2">.</span>HIGH<span style="color:#f8f8f2">:</span>k <span style="color:#f8f8f2">+</span><span style="color:#f8f8f2">=</span> <span style="color:#ae81ff"><span style="color:#ae81ff">1</span></span><span style="color:#66d9ef"><span style="color:#f92672">if</span></span> k <span style="color:#f8f8f2">></span> <span style="color:#ae81ff"><span style="color:#ae81ff">100</span></span><span style="color:#f8f8f2">:</span><span style="color:#66d9ef"><span style="color:#f92672">break</span></span><span style="color:#66d9ef"><span style="color:#f92672">if</span></span> k <span style="color:#f8f8f2"><</span> <span style="color:#ae81ff"><span style="color:#ae81ff">8</span></span><span style="color:#f8f8f2">:</span>data<span style="color:#f8f8f2">.</span><span style="color:#e6db74">append</span><span style="color:#f8f8f2">(</span><span style="color:#ae81ff"><span style="color:#ae81ff">0</span></span><span style="color:#f8f8f2">)</span><span style="color:#66d9ef"><span style="color:#f92672">else</span></span><span style="color:#f8f8f2">:</span>data<span style="color:#f8f8f2">.</span><span style="color:#e6db74">append</span><span style="color:#f8f8f2">(</span><span style="color:#ae81ff"><span style="color:#ae81ff">1</span></span><span style="color:#f8f8f2">)</span> j <span style="color:#f8f8f2">+</span><span style="color:#f8f8f2">=</span> <span style="color:#ae81ff"><span style="color:#ae81ff">1</span></span>humidity_bit <span style="color:#f8f8f2">=</span> data<span style="color:#f8f8f2">[</span><span style="color:#ae81ff"><span style="color:#ae81ff">0</span></span><span style="color:#f8f8f2">:</span><span style="color:#ae81ff"><span style="color:#ae81ff">8</span></span><span style="color:#f8f8f2">]</span>humidity_point_bit <span style="color:#f8f8f2">=</span> data<span style="color:#f8f8f2">[</span><span style="color:#ae81ff"><span style="color:#ae81ff">8</span></span><span style="color:#f8f8f2">:</span><span style="color:#ae81ff"><span style="color:#ae81ff">16</span></span><span style="color:#f8f8f2">]</span>temperature_bit <span style="color:#f8f8f2">=</span> data<span style="color:#f8f8f2">[</span><span style="color:#ae81ff"><span style="color:#ae81ff">16</span></span><span style="color:#f8f8f2">:</span><span style="color:#ae81ff"><span style="color:#ae81ff">24</span></span><span style="color:#f8f8f2">]</span>temperature_point_bit <span style="color:#f8f8f2">=</span> data<span style="color:#f8f8f2">[</span><span style="color:#ae81ff"><span style="color:#ae81ff">24</span></span><span style="color:#f8f8f2">:</span><span style="color:#ae81ff"><span style="color:#ae81ff">32</span></span><span style="color:#f8f8f2">]</span>check_bit <span style="color:#f8f8f2">=</span> data<span style="color:#f8f8f2">[</span><span style="color:#ae81ff"><span style="color:#ae81ff">32</span></span><span style="color:#f8f8f2">:</span><span style="color:#ae81ff"><span style="color:#ae81ff">40</span></span><span style="color:#f8f8f2">]</span>humidity <span style="color:#f8f8f2">=</span> <span style="color:#ae81ff"><span style="color:#ae81ff">0</span></span>humidity_point <span style="color:#f8f8f2">=</span> <span style="color:#ae81ff"><span style="color:#ae81ff">0</span></span>temperature <span style="color:#f8f8f2">=</span> <span style="color:#ae81ff"><span style="color:#ae81ff">0</span></span>temperature_point <span style="color:#f8f8f2">=</span> <span style="color:#ae81ff"><span style="color:#ae81ff">0</span></span>check <span style="color:#f8f8f2">=</span> <span style="color:#ae81ff"><span style="color:#ae81ff">0</span></span><span style="color:#66d9ef"><span style="color:#f92672">for</span></span> i in <span style="color:#e6db74">range</span><span style="color:#f8f8f2">(</span><span style="color:#ae81ff"><span style="color:#ae81ff">8</span></span><span style="color:#f8f8f2">)</span><span style="color:#f8f8f2">:</span>humidity <span style="color:#f8f8f2">+</span><span style="color:#f8f8f2">=</span> humidity_bit<span style="color:#f8f8f2">[</span>i<span style="color:#f8f8f2">]</span> <span style="color:#f8f8f2">*</span> <span style="color:#ae81ff"><span style="color:#ae81ff">2</span></span> <span style="color:#f8f8f2">*</span><span style="color:#f8f8f2">*</span> <span style="color:#f8f8f2">(</span><span style="color:#ae81ff"><span style="color:#ae81ff">7</span></span><span style="color:#f8f8f2">-</span>i<span style="color:#f8f8f2">)</span>humidity_point <span style="color:#f8f8f2">+</span><span style="color:#f8f8f2">=</span> humidity_point_bit<span style="color:#f8f8f2">[</span>i<span style="color:#f8f8f2">]</span> <span style="color:#f8f8f2">*</span> <span style="color:#ae81ff"><span style="color:#ae81ff">2</span></span> <span style="color:#f8f8f2">*</span><span style="color:#f8f8f2">*</span> <span style="color:#f8f8f2">(</span><span style="color:#ae81ff"><span style="color:#ae81ff">7</span></span><span style="color:#f8f8f2">-</span>i<span style="color:#f8f8f2">)</span>temperature <span style="color:#f8f8f2">+</span><span style="color:#f8f8f2">=</span> temperature_bit<span style="color:#f8f8f2">[</span>i<span style="color:#f8f8f2">]</span> <span style="color:#f8f8f2">*</span> <span style="color:#ae81ff"><span style="color:#ae81ff">2</span></span> <span style="color:#f8f8f2">*</span><span style="color:#f8f8f2">*</span> <span style="color:#f8f8f2">(</span><span style="color:#ae81ff"><span style="color:#ae81ff">7</span></span><span style="color:#f8f8f2">-</span>i<span style="color:#f8f8f2">)</span>temperature_point <span style="color:#f8f8f2">+</span><span style="color:#f8f8f2">=</span> temperature_point_bit<span style="color:#f8f8f2">[</span>i<span style="color:#f8f8f2">]</span> <span style="color:#f8f8f2">*</span> <span style="color:#ae81ff"><span style="color:#ae81ff">2</span></span> <span style="color:#f8f8f2">*</span><span style="color:#f8f8f2">*</span> <span style="color:#f8f8f2">(</span><span style="color:#ae81ff"><span style="color:#ae81ff">7</span></span><span style="color:#f8f8f2">-</span>i<span style="color:#f8f8f2">)</span>check <span style="color:#f8f8f2">+</span><span style="color:#f8f8f2">=</span> check_bit<span style="color:#f8f8f2">[</span>i<span style="color:#f8f8f2">]</span> <span style="color:#f8f8f2">*</span> <span style="color:#ae81ff"><span style="color:#ae81ff">2</span></span> <span style="color:#f8f8f2">*</span><span style="color:#f8f8f2">*</span> <span style="color:#f8f8f2">(</span><span style="color:#ae81ff"><span style="color:#ae81ff">7</span></span><span style="color:#f8f8f2">-</span>i<span style="color:#f8f8f2">)</span>tmp <span style="color:#f8f8f2">=</span> humidity <span style="color:#f8f8f2">+</span> humidity_point <span style="color:#f8f8f2">+</span> temperature <span style="color:#f8f8f2">+</span> temperature_point<span style="color:#66d9ef"><span style="color:#f92672">if</span></span> check <span style="color:#f8f8f2">==</span> tmp<span style="color:#f8f8f2">:</span><span style="color:#66d9ef"><span style="color:#f92672">return</span></span> temperature<span style="color:#f8f8f2">,</span>humidity<span style="color:#66d9ef"><span style="color:#f92672">else</span></span><span style="color:#f8f8f2">:</span>print <span style="color:#a6e22e"><span style="color:#e6db74">"wrong"</span></span><span style="color:#66d9ef"><span style="color:#f92672">return</span></span> <span style="color:#ae81ff"><span style="color:#ae81ff">0</span></span><span style="color:#f8f8f2">,</span><span style="color:#ae81ff"><span style="color:#ae81ff">0</span></span> </code></span>
这些准备工作做好后,我们要在云端定义相关产品和设备了。和阿里云官方示例不一样的是,我们额外增加了一个属性LED,具备读写能力,枚举型变量,0-表示关灯,1-表示开灯
这个定义好后,我们创建设备,并且获取设备的三元组。由于官方提供的示例仅仅是模拟数据,并且是单向上传,我们需要改造一下。
在main函数里,增加这句代码:
<span style="color:#f8f8f2"><code class="language-c">client<span style="color:#f8f8f2">.</span>on_message <span style="color:#f8f8f2">=</span> on_message</code></span>
表示我们可以获取云端推送的信息。
我们云端推送的信息内容如下:
<span style="color:#f8f8f2"><code class="language-c"><span style="color:#f8f8f2">{</span><span style="color:#a6e22e"><span style="color:#e6db74">"method"</span></span><span style="color:#f8f8f2">:</span><span style="color:#a6e22e"><span style="color:#e6db74">"thing.service.property.set"</span></span><span style="color:#f8f8f2">,</span><span style="color:#a6e22e"><span style="color:#e6db74">"id"</span></span><span style="color:#f8f8f2">:</span><span style="color:#a6e22e"><span style="color:#e6db74">"169885527"</span></span><span style="color:#f8f8f2">,</span><span style="color:#a6e22e"><span style="color:#e6db74">"params"</span></span><span style="color:#f8f8f2">:</span><span style="color:#f8f8f2">{</span><span style="color:#a6e22e"><span style="color:#e6db74">"LED"</span></span><span style="color:#f8f8f2">:</span><span style="color:#ae81ff"><span style="color:#ae81ff">1</span></span><span style="color:#f8f8f2">}</span><span style="color:#f8f8f2">,</span><span style="color:#a6e22e"><span style="color:#e6db74">"version"</span></span><span style="color:#f8f8f2">:</span><span style="color:#a6e22e"><span style="color:#e6db74">"1.0.0"</span></span><span style="color:#f8f8f2">}</span></code></span>
我们需要获取LED的值,所以on_message函数我们要增加一些内容:
<span style="color:#f8f8f2"><code class="language-c">setjson <span style="color:#f8f8f2">=</span> json<span style="color:#f8f8f2">.</span><span style="color:#e6db74">loads</span><span style="color:#f8f8f2">(</span>msg<span style="color:#f8f8f2">.</span>payload<span style="color:#f8f8f2">)</span>led <span style="color:#f8f8f2">=</span> setjson<span style="color:#f8f8f2">[</span><span style="color:#a6e22e"><span style="color:#e6db74">'params'</span></span><span style="color:#f8f8f2">]</span><span style="color:#f8f8f2">[</span><span style="color:#a6e22e"><span style="color:#e6db74">'LED'</span></span><span style="color:#f8f8f2">]</span>
GPIO<span style="color:#f8f8f2">.</span><span style="color:#e6db74">output</span><span style="color:#f8f8f2">(</span>led_pin<span style="color:#f8f8f2">,</span><span style="color:#f8f8f2">(</span>GPIO<span style="color:#f8f8f2">.</span>HIGH <span style="color:#66d9ef"><span style="color:#f92672">if</span></span> led<span style="color:#f8f8f2">==</span><span style="color:#ae81ff"><span style="color:#ae81ff">1</span></span> <span style="color:#66d9ef"><span style="color:#f92672">else</span></span> GPIO<span style="color:#f8f8f2">.</span>LOW <span style="color:#f8f8f2">)</span><span style="color:#f8f8f2">)</span></code></span>
根据led的值,我们开灯或者关灯。
相关代码修改好后,我们就可以上传到树莓派设备,开始运行了,如下图所示:
这个时候我们查看云端设备的状态,会发现数据已经正常上传到云端了。
我们在云端产品的在线调试面板进行数据下发测试
我们发送0或1,会发现LED灭或亮了。
以上,我们会发现通过我们所熟悉的Python语言,就可以轻松编写物联网代码了。
本文相关的代码文件:alios_ht_all.py
原文链接
本文为云栖社区原创内容,未经允许不得转载。