利用 AWS IoT Greengrass 在边缘 DIY 自动浇花 | 手把手玩转物联网(三)

阅读数:1 2020 年 1 月 9 日 15:57

利用 AWS IoT Greengrass 在边缘 DIY 自动浇花 | 手把手玩转物联网(三)

安装 AWS IoT Greengrass 核心软件

首先在 AWS IoT 控制台配置 AWS IoT Greengrass。在 Greengrass 界面,创建组 waterflower,详细步骤可参见链接: https://docs.aws.amazon.com/zh_cn/greengrass/latest/developerguide/gg-config.html。

创建过程中,会下载安全资源 tar.gz 文件,并下载 AWS IoT Greengrass 核心软件安装包(适用于 Raspbian 的 Armv7l 软件包)。

将下载的文件利用 scp 上传到树莓派设备上:

Python

复制代码
$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

登录到树莓派设备,进入到对应下载文件的目录并解压这两个到相应路径下:

Python

复制代码
$sudo tar -xzvf greengrass-linux-armv7l-1.10.0.tar.gz -C /
$sudo tar -xzvf <hash>-setup.tar.gz -C /greengrass

下载 AWS IoT 服务器根证书:

Python

复制代码
$cd /greengrass/certs/
$sudo wget -O root.ca.pem https://www.amazontrust.com/repository/AmazonRootCA1.pem

启动 AWS IoT Greengrass:

Python

复制代码
$cd /greengrass/ggc/core/
$sudo ./greengrassd start

确定传感器和 AWS IoT Greengrass 的交互模式

传感器作为本地设备,和 AWS IoT Greengrass 之间可以采用两种交互模式:一种是标准的 IoT 模式,即每个传感器作为独立的设备,有自己的 X.509 证书,通过 MQTT 协议与 AWS IoT Greengrass Core 进行通信,AWS IoT Greengrass Core 则通过 MQTT 协议对继电器设备发出控制命令。如果需要,AWS IoT Greengrass Core 也负责对收集的各个传感器消息进行汇总并上传给 AWS IoT Core。另一种是简化模式,即每个传感器作为树莓派本地设备,AWS IoT Greengrass 上的 AWS Lambda 函数利用本地资源访问功能通过 GrovePi SDK 对传感器和继电器设备进行读取和写入操作。

第一种模式的扩展性好,支持容器化部署,每个传感器作为 IoT 设备加入到 AWS IoT Greengrass 组中,但每个设备都需要编写相应的代码。这种模式的参考范例也比较容易找到。第二种模式编程简单,两个 Lambda 函数就可以搞定。在本文中将介绍如何用第二种模式实现。

编写和打包 AWS Lambda 函数

首先编写读取和报告传感器状态的 Lambda 函数,这里命名为 wfSensorLambda.py。

为了利用 GrovePi SDK 来读取传感器数据,并在本地 LCD 屏上设置文本和颜色,需要引入两个包:

Python

复制代码
import grovepi
from grove_rgb_lcd import *

读取传感器数据的代码如下:

Python

复制代码
# 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 屏上设置颜色和文本的代码如下:

Python

复制代码
setRGB(R, G, B)
setText("Temp: %.1f C *%s\nMoisture: %d " %(temp_value,moment,mois_value))

由于 LCD 屏的 RGB 背光色有 255 个值,为了通过 LCD 屏的颜色能一目了然地了解当前土壤湿度情况,我们需要将土壤湿度值按照颜色梯度映射到这 255 个值然后进行显示,从而实现土壤湿度值的颜色显示。这里实现了两个函数来计算最终的 RGB 值,代码如下:

Python

复制代码
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 秒采集一次传感器数据:

Python

复制代码
Timer(5, greengrass_sensor_run).start()

wfSensorLambda.py 的完整源代码可以从这里获取。

为了实现对继电器和水泵的控制,我们还需要编写一个实现设备控制的 AWS Lambda 函数,这里命名为 wfSwitchLambda.py。它有两个作用:一是根据传感器数据和设定阈值,执行相应的决策逻辑,控制继电器状态以启动或关闭水泵;二是接收来自 AWS IoT 的阈值设置消息,更新阈值。

为了避免浇水过快而传感器不能及时感知的问题,在控制逻辑中针对不同环境条件采取了反转模式或步进模式来启停水泵。主要代码如下:

Python

复制代码
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 目录可以从 AWS Greengrass Core SDK for Python 中获取。打包命令如下:

Python

复制代码
$zip -r wf_sensor_lambda.zip greengrasssdk wfSensorLambda.py
$zip -r wf_switch_lambda.zip greengrasssdk wfSwitchLambda.py

然后,打开 AWS Lambda 控制台,分别创建这两个函数 wfSensor 和 wfSwitch:

  • Runtime 请选择 Python 3.7
  • 对于代码输入种类,请选择上传 zip 文件
  • 对于 Handler(处理程序),分别输入 wfSensorLambda.function_handler 和 wfSwitchLambda.switch_handler
  • 分别上传 wf_sensor_lambda.zip 和 wf_switch_lambda.zip
  • 发布函数后,建议为函数创建别名

本文转载自 AWS 技术博客。

原文链接: https://amazonaws-china.com/cn/blogs/china/diy-auto-watering-at-the-edge-with-aws-iot-greengrass-hand-to-hand-internet-of-things/

评论

发布