物联网IoT之DIY 自动浇花
自动浇花思路
通过树莓派和IoT Core建立连接
利用光传感器、温度传感器和土壤湿度传感器检测环境亮度、温度及花盆中湿度,通过树莓派汇总后上传
利用LCD屏在本地显示传感器数据信息,并以不同颜色醒目提示土壤湿度状况
利用继电器控制小水泵进行浇水
在树莓派上运行自动控制逻辑,根据亮度、温度和湿度确定继电器状态
通过topic来设置湿度阈值,这样可以很方便地实现通过手机App或Web应用进行参数设置
将传感器数据和继电器状态通过IoT的规则引擎发送到Elasticsearch,建立监控仪表板,这样可以很方便地通过手机或浏览器进行可视化监控
方案架构如下图所示:
材料准备
树莓派 Raspberry Pi 3B/3B+ 一个,MicroSD卡一张
GrovePi+ 树莓派扩展板一个
三个Grove传感器配件:温度传感器,土壤湿度传感器,亮度传感器
Grove 1602 LCD RGB背光显示屏一个
一个继电器配件(Grove Ralay)
微型水泵一个(3V/5V/6V),水泵水管一条
设备连接
首先将GrovePi+安装在Raspberry Pi上。堆叠GrovePi+时,注意引脚对齐,如下图所示。
按照以下对应端口连接设备配件:
温度传感器:A0
土壤湿度传感器:A1
亮度传感器:A2
继电器:D6
LCD显示屏:I2C-2
水泵的地线与水泵电源线(可使用USB电源线)的地线分别接入继电器的端子
安装和配置树莓派设备
树莓派运行系统建议使用原生Raspbian,目前最新版本为buster。请从Raspberry Pi官方网站下载并使用Etcher工具制作启动镜像。
为方便后续使用和调试,建议启用SSH:
$sudo systemctl enable ssh
一键安装全部驱动:
$sudo curl -kL dexterindustries.com/update_grovepi | bash
安装AWS IoT SDK:
$ pip3 install AWSIoTPythonSDK
记得安装好所有依赖后reboot一下,以刷新系统驱动。
IoT Greengrass环境配置
首先设置IoT Greengrass运行环境,增加以下用户和组:
$sudo adduser --system ggc_user $sudo addgroup --system ggc_group
为树莓派设置hardlink 和 softlink 保护,在 /etc/sysctl.d/98-rpi.conf中增加以下两行:
fs.protected_hardlinks = 1 fs.protected_symlinks = 1
编辑 /boot/cmdline.txt,在行末尾,增加如下参数,激活memory cgroups:
cgroup_enable=memory cgroup_memory=1
配置完成后,重启树莓派。
运行Greengrass dependency checker,确保树莓派环境满足所有依赖条件:
$cd /home/pi/Downloads $wget https://github.com/aws-samples/aws-greengrass-samples/raw/master/greengrass-dependency-checker-GGCv1.10.x.zip $unzip greengrass-dependency-checker-GGCv1.10.x.zip $cd greengrass-dependency-checker-GGCv1.10.x $sudo modprobe configs $sudo ./check_ggc_dependencies
安装IoT Greengrass核心软件
创建过程中,会下载安全资源 tar.gz文件,并下载IoT Greengrass 核心软件安装包(适用于 Raspbian 的 Armv7l 软件包)。
将下载的文件利用scp上传到树莓派设备上:
$scp greengrass-linux-armv7l-1.10.0.tar.gz pi@raspberry-IP-address:/home/pi $scp <hash>-setup.tar.gz pi@raspberry-IP-address:/home/pi
登录到树莓派设备,进入到对应下载文件的目录并解压这两个到相应路径下:
$sudo tar -xzvf greengrass-linux-armv7l-1.10.0.tar.gz -C / $sudo tar -xzvf <hash>-setup.tar.gz -C /greengrass
下载IoT服务器根证书:
$cd /greengrass/certs/ $sudo wget -O root.ca.pem https://www.amazontrust.com/repository/AmazonRootCA1.pem
启动IoT Greengrass:
$cd /greengrass/ggc/core/ $sudo ./greengrassd start
确定传感器和IoT Greengrass的交互模式
传感器作为本地设备,和IoT Greengrass之间可以采用两种交互模式:一种是标准的IoT模式,即每个传感器作为独立的设备,有自己的X.509证书,通过MQTT协议与IoT Greengrass Core进行通信,IoT Greengrass Core则通过MQTT协议对继电器设备发出控制命令。如果需要,IoT Greengrass Core也负责对收集的各个传感器消息进行汇总并上传给IoT Core。另一种是简化模式,即每个传感器作为树莓派本地设备,IoT Greengrass上的Lambda函数利用本地资源访问功能通过GrovePi SDK对传感器和继电器设备进行读取和写入操作。
第一种模式的扩展性好,支持容器化部署,每个传感器作为IoT 设备加入到IoT Greengrass组中,但每个设备都需要编写相应的代码。这种模式的参考范例也比较容易找到。第二种模式编程简单,两个Lambda函数就可以搞定。在本文中将介绍如何用第二种模式实现。
编写和打包AWS Lambda函数
首先编写读取和报告传感器状态的Lambda函数,这里命名为wfSensorLambda.py。
为了利用GrovePi SDK来读取传感器数据,并在本地LCD屏上设置文本和颜色,需要引入两个包:
import grovepi from grove_rgb_lcd import *
读取传感器数据的代码如下:
# Get value from temperature sensor temp_value = grovepi.temp(temp_sensor,"1.2") # Get value from moisture sensor mois_value = grovepi.analogRead(mois_sensor) # Get value from light sensor light_value = grovepi.analogRead(light_sensor) # Get status from relay switch_status = grovepi.digitalRead(relay)
在LCD屏上设置颜色和文本的代码如下:
setRGB(R, G, B) setText("Temp: %.1f C *%s\nMoisture: %d " %(temp_value,moment,mois_value))
由于LCD屏的RGB背光色有255个值,为了通过LCD屏的颜色能一目了然地了解当前土壤湿度情况,我们需要将土壤湿度值按照颜色梯度映射到这255个值然后进行显示,从而实现土壤湿度值的颜色显示。这里实现了两个函数来计算最终的RGB值,代码如下:
def calcColorAdj(variance): # Calc the adjustment value of the background color "Because there is 200 mapping to 255 values, 1.275 is the factor for 400 spread" factor = 1.275; adj = abs(int(factor * variance)); if adj > 255: adj = 255; return adj; def calcBG(humidity): "This calculates the color value for the background" variance = humidity - justRight; # Calculate the variance adj = calcColorAdj(variance); # Scale it to 8 bit int bgList = [0,0,0] # initialize the color array if(variance < 0): bgR = 0; # too dry, no red bgB = adj; # green and blue slide equally with adj bgG = 255 - adj; elif(variance == 0): # perfect, all on green bgR = 0; bgB = 0; bgG = 255; elif(variance > 0): #too wet - no blue bgB = 0; bgR = adj; # Red and Green slide equally with Adj bgG = 255 - adj; bgList = [bgR,bgG,bgB] #build list of color values to return return bgList;
报告传感器状态则比较简单,直接调用greengrass SDK的publish函数即可。
由于需要周期性地采集传感器的数据,因此,这个Lambda函数需要长时间运行,这里我们利用threading的Timer实现每5秒采集一次传感器数据:
Timer(5, greengrass_sensor_run).start()
wfSensorLambda.py的完整源代码可以从这里获取。
为了实现对继电器和水泵的控制,我们还需要编写一个实现设备控制的Lambda函数,这里命名为wfSwitchLambda.py。它有两个作用:一是根据传感器数据和设定阈值,执行相应的决策逻辑,控制继电器状态以启动或关闭水泵;二是接收来自IoT的阈值设置消息,更新阈值。
为了避免浇水过快而传感器不能及时感知的问题,在控制逻辑中针对不同环境条件采取了反转模式或步进模式来启停水泵。主要代码如下:
temp_value = float(event['temp']) mois_value = int(event['moisture']) light_value = int(event['light']) status = int(event['switch']) if mois_value < threshold: if ((light_value > light_threshold) and (temp_value > temp_threshold)): ##反转模式 if status: state = "off" else: state = "on" else: ## 步进模式 state = "on-1" else: if status: state = "off" grovepi.pinMode(relay,"OUTPUT") if state == "on": # 反转模式 try: grovepi.digitalWrite(relay,1) logger.info("Triggering relay turned ON!") except Exception as e: logger.error("Failed to switch ON relay: " + repr(e)) elif state == "on-1": # 步进模式 try: grovepi.digitalWrite(relay,1) logger.info("Triggering relay turned ON - one time!") time.sleep(1) grovepi.digitalWrite(relay,0) except Exception as e: logger.error("Failed to switch ON relay[one time]: " + repr(e)) elif state == "off": try: grovepi.digitalWrite(relay,0) logger.info("Triggering relay turned OFF!") except Exception as e: logger.error("Failed to switch OFF relay: " + repr(e)) else: logger.info("No need to change!")
wfSwitchLambda.py 的完整源代码可以从这里获取。
在编写好Lambda函数后,需要将其打包成zip文件。打包时,需要注意将greengrasssdk目录一起打包到zip文件中,greengrasssdk目录可以从Greengrass Core SDK for Python中获取。打包命令如下:
$zip -r wf_sensor_lambda.zip greengrasssdk wfSensorLambda.py $zip -r wf_switch_lambda.zip greengrasssdk wfSwitchLambda.py
然后,打开 Lambda 控制台,分别创建这两个函数 wfSensor 和 wfSwitch:
Runtime请选择 Python 3.7
对于代码输入种类,请选择上传zip文件
对于Handler(处理程序),分别输入wfSensorLambda.function_handler 和 wfSwitchLambda.switch_handler
分别上传wf_sensor_lambda.zip 和 wf_switch_lambda.zip
发布函数后,建议为函数创建别名
为IoT Greengrass配置和部署Lambda函数
选择之前创建的Greengrass组,在配置页面上,选择Lambdas,然后点击两次Add Lamba,分别将 wfSensor 和 wfSwitch 加入,添加时注意以下要点:
选择Use existing Lambda
在选择版本时,不要选择具体版本号,而是选择Alias:xxx
在加入的函数右上角点击省略号(…),选择Edit Configuration(编辑配置)
对于“Run as”,请选择Another user ID/group ID,在下方输入两个0,对于“containerization”,选择No container(always)。这个修改只是针对第二种交互模式,对于第一种交互模式,无需修改。
Timeout超时值改为10秒
对于Lamba生命周期,wfSensor需要改为long-lived;wfSwitchLambda不用修改。
配置如下订阅:
Source 源 | Target目标 | Topic 主题 |
wfSensor | IoT Cloud | waterflower/sensor/telemetry |
wfSensor | wfSwitch | waterflower/sensor/telemetry |
wfSwitch | IoT Cloud | waterflower/relay |
IoT Cloud | wfSwitch | waterflower/setting |
针对本文的第二种交互模式,需要在树莓派上修改IoT Greengrass的参数。打开 /greengrass/config/config.json,在 “runtime”部分,增加:
"allowFunctionsToRunAsRoot" : "yes"
在IoT控制台上,在相应greengrass组中,点击Deploy部署,将云配置部署到树莓派设备。第一次部署可能需要几分钟。当部署完成后,您应该在部署页面上的状态列中看到已成功完成。
创建和配置Elasticsearch
在Elasticsearch控制台上,创建一个新域,名称为waterflower,网络配置选择“Public access”,并输入以下 Access policy(访问策略):
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "es:*", "Resource": "arn:aws-cn:es:<region>:<your-Account-ID>:domain/waterflower/*", "Condition": { "IpAddress": { "aws:SourceIp": [ "x.x.x.x/32" ] } } } ]}
上面“x.x.x.x”请输入您的电脑对应的公网IP地址。
访问Kibana界面,创建index,命名为wf-sensor:
PUT /wf-sensor{ "mappings": { "properties": { "timestamp": { "type": "long", "copy_to": "datetime" }, "datetime": { "type": "date", "store": true }, "clientId": { "type": "text" }, "temp": { "type": "float" }, "moisture": { "type": "integer" }, "light": { "type": "integer" }, "switch": { "type": "integer" }, "state": { "type": "integer" } } }}
创建index pattern:
名称:wf-sensor*
时间过滤器字段名称:datetime
配置IoT规则引擎
在IoT控制台中,点击Act->Rules,创建规则:
规则查询条件:SELECT * FROM ‘waterflower/sensor/telemetry’
添加Action,选择 Send a message to the Amazon Elasticsearch Service
选择Domain(域)waterflower
ID: ${newuuid()}
Index: wf-sensor
Type: _doc
创建可视化报表
在Kibana界面,点击左边菜单栏的Discover(发现),您现在可以看到上传的设备状态数据,它们按时间顺序显示在屏幕上。
点击左边菜单栏的Visualize,您现在可以创建可视化图表,并可以添加到仪表板中,以远程监控和查看传感器状态和继电器/水泵工作情况。如下图示例:
测试和验证
您可以通过以下几个方法验证自动浇花效果:
利用IoT控制台的test功能发布消息到waterflower/setting,修改湿度阈值,测试水泵工作情况
通过Elasticsearch的Kibana界面,查看传感器数据变化情况和水泵工作情况
关闭树莓派的互联网连接,验证连接丢失的条件下,自动浇花是否正常工作
资源清理
在您成功搭建了本文介绍的自动浇花系统后,根据您的使用需求,可以按照如下两种情况对创建的资源进行清理,以免产生不必要的费用。
如果您想继续使用自动浇花功能,但不再需要进行远程监控,请按以下步骤删除资源:
打开IoT控制台,依次选择 Act -> Rules,点击之前创建的规则waterflower的右上角省略号(…),点击删除并确认
打开Elasticsearch控制台,可以看到之前创建的域 waterflower,点击进入。然后,点击最上面一排的“Delete domain(删除域)”按钮,在弹出窗口中,选中checkbox框,然后点击删除
如果您不再使用整个自动浇花系统,请先按上面步骤删除远程监控相关的资源,然后按以下步骤继续清理所有资源:
SSH到树莓派,输入以下命令停止greengrass进程:
$sudo /greengrass/ggc/core/greengrassd stop
打开IoT控制台,点击左边菜单栏中的 Greengrass -> Groups,点击之前创建的组waterflower,进入组管理界面,点击右上角的Actions -> Reset Deployments,在弹出窗口中,选中checkbox框,点击Reset deployment
接着点击右上角的 Actions -> Delete Group,在弹出窗口中,点击“Yes, Continue to delete”按钮,确认删除
继续在IoT控制台,点击左边的Manage -> Things,点击waterflower_Core的右上角省略号(…),点击删除并确认
小结
根据上面的方案实现,您可能会发现在 树莓派系统上运行 IoT Greengrass 可以构建更多的IoT解决方案。从基本的遥测到执行机器学习推理,我们的客户正在构建多种多样的 IoT Greengrass 解决方案,以便不断创新并扩展解决方案的价值。
在本文中,您学习了如何利用IoT Greengrass DIY一个自动浇花系统。现在,您可以扩展这个方案,增加手机App实现对浇花参数控制和远程监控自动浇花工作状况,并利用IoT Greengrass 不断改进您的边缘功能。
- 点赞
- 收藏
- 关注作者
评论(0)