写点什么

利用 Amazon IoT Greengrass 在边缘 DIY 自动浇花系统

  • 2021 年 12 月 24 日
  • 本文字数:8691 字

    阅读完需:约 29 分钟

利用 Amazon IoT Greengrass 在边缘 DIY 自动浇花系统



曾经有这样一则新闻,一男子智能养鱼遇断网,4 万余斤鱼或因缺氧死亡。这个塘主通过手机 App 监控鱼塘情况并利用智能插座控制增氧机进行增氧;但因遇到网络故障,无法及时为鱼塘启动增氧设备而造成重大经济损失。这是个典型的物联网案例,利用物联网平台远程监控数据,并基于数据进行设备控制。在大多数情况下,它能够很好地工作,但当网络连接丢失时,智能将变得无能为力。生活中类似的场景很多,我们有没有办法既享受物联网带来的便捷和智能,又能够摆脱网络依赖带来的局限性呢?


本文将介绍如何利用 Amazon IoT Greengrass 边缘计算能力,实现远程监控的同时,在边缘侧进行智能控制。为了便于大家有一个直观、清晰的理解,全文以 DIY 自动浇花为主线展开介绍。


概述


Amazon IoT Greengrass 是 Amazon IoT 服务系列中的一员,它可将亚马逊云科技无缝扩展至边缘设备,因此可以在本地操作其生成的数据,同时仍可将云用于管理、分析和持久存储。借助 Amazon IoT Greengrass,您可以构建 IoT 解决方案,从而将不同类型的设备和云连接起来,并实现设备互连。运行 Linux 的设备和支持 Arm 或 x86 架构的设备可以托管 Amazon IoT Greengrass Core。Amazon IoT Greengrass 可在本地执行 Amazon Lambda 代码、消息收发、数据管理和安全策略,甚至在没有连接 Internet 的情况下,也可实现这些功能。运行 Amazon IoT Greengrass Core 的设备充当枢纽,与其他运行 Amazon FreeRTOS 或已安装 Amazon IoT Device SDK 的设备进行通信。这些设备的尺寸可能不同,从较小的基于微控制器的设备到大型设备。如果 Amazon IoT Greengrass Core 设备与云之间的连接断开,Amazon IoT Greengrass 组中的设备还可通过本地网络继续相互通信。



📢 想学习 Amazon IoT Greengrass 的更多玩法?来 2021 亚马逊云科技中国峰会与业内领先的技术践行者们一起探讨交流吧!点击图片报名吧~


Amazon IoT Greengrass 具有以下优势:

  • 近乎实时地响应本地事件。本地资源访问功能让部署在 Amazon IoT Greengrass Core 设备上的 Amazon Lambda 函数使用本地设备资源,这样设备应用程序就能够快速访问和处理本地数据。

  • 本地运行。Amazon IoT Greengrass 设备可以在本地设备无法连接到云的情况下收集、处理和导出数据流。在设备重新连接到云后,Amazon IoT Greengrass 可将设备上的数据与 Amazon 云服务同步。

  • 安全通信。Amazon IoT Greengrass 可对本地和云通信的设备进行身份验证和加密,包括采用硬件保护的端到端加密。

  • 简化设备编程。您可以在云中开发代码,然后使用 Amazon Lambda、Docker 容器,无缝地将其部署到您的设备上。

  • 降低运行 IoT 应用程序的成本。通过对设备进行编程以在本地过滤或汇总数据,并只将应用程序所需的数据传输到云,从而以较低的成本获得丰富的见解。

  • 多平台支持。您可以在支持最低硬件和软件要求的任何硬件设备上运行 Amazon IoT Greengrass 软件。


自动浇花思路


  • 通过树莓派和 Amazon IoT Core 建立连接

  • 利用光传感器、温度传感器和土壤湿度传感器检测环境亮度、温度及花盆中湿度,通过树莓派汇总后上传

  • 利用 LCD 屏在本地显示传感器数据信息,并以不同颜色醒目提示土壤湿度状况

  • 利用继电器控制小水泵进行浇水

  • 在树莓派上运行自动控制逻辑,根据亮度、温度和湿度确定继电器状态

  • 通过 topic 来设置湿度阈值,这样可以很方便地实现通过手机 App 或 Web 应用进行参数设置

  • 将传感器数据和继电器状态通过 Amazon IoT 的规则引擎发送到 Amazon 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:


1$sudo systemctl enable ssh
复制代码


一键安装全部驱动:


1$sudo curl -kL dexterindustries.com/update_grovepi | bash
复制代码


安装 Amazon IoT SDK:


1$ pip3 install AWSIoTPythonSDK
复制代码


记得安装好所有依赖后 reboot 一下,以刷新系统驱动。


Amazon IoT Greengrass 环境配置


首先设置 Amazon IoT Greengrass 运行环境,增加以下用户和组:


1$sudo adduser --system ggc_user2$sudo addgroup --system ggc_group
复制代码


为树莓派设置 hardlink 和 softlink 保护,在 /etc/sysctl.d/98-rpi.conf 中增加以下两行:


1fs.protected_hardlinks = 12fs.protected_symlinks = 1
复制代码


编辑 /boot/cmdline.txt,在行末尾,增加如下参数,激活 memory cgroups:


1cgroup_enable=memory cgroup_memory=1
复制代码


配置完成后,重启树莓派。


运行 Greengrass dependency checker,确保树莓派环境满足所有依赖条件:


1$cd /home/pi/Downloads2$wget https://github.com/aws-samples/aws-greengrass-samples/raw/master/greengrass-dependency-checker-GGCv1.10.x.zip3$unzip greengrass-dependency-checker-GGCv1.10.x.zip4$cd greengrass-dependency-checker-GGCv1.10.x5$sudo modprobe configs6$sudo ./check_ggc_dependencies
复制代码


安装 Amazon IoT Greengrass 核心软件


首先在 Amazon IoT 控制台配置 Amazon IoT Greengrass。在 Greengrass 界面,创建组 waterflower,详细步骤可参见链接。


  • 链接:

https://docs.aws.amazon.com/zh_cn/greengrass/latest/developerguide/gg-config.html


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


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


1$scp greengrass-linux-armv7l-1.10.0.tar.gz pi@raspberry-IP-address:/home/pi2$scp <hash>-setup.tar.gz pi@raspberry-IP-address:/home/pi
复制代码


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


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


下载 Amazon IoT 服务器根证书:


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


启动 Amazon IoT Greengrass:


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


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


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


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


编写和打包 Amazon Lambda 函数


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


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


1import grovepi2from grove_rgb_lcd import *
复制代码


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


 1# Get value from temperature sensor 2temp_value = grovepi.temp(temp_sensor,"1.2") 3 4# Get value from moisture sensor 5mois_value = grovepi.analogRead(mois_sensor) 6 7# Get value from light sensor 8light_value = grovepi.analogRead(light_sensor) 910# Get status from relay11switch_status = grovepi.digitalRead(relay)
复制代码


在 LCD 屏上设置颜色和文本的代码如下:


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


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


 1def calcColorAdj(variance):     # Calc the adjustment value of the background color 2    "Because there is 200 mapping to 255 values, 1.275 is the factor for 400 spread" 3    factor = 1.275; 4    adj = abs(int(factor * variance)); 5    if adj > 255: 6        adj = 255; 7    return adj; 8 9def calcBG(humidity):10    "This calculates the color value for the background"11    variance = humidity - justRight;   # Calculate the variance12    adj = calcColorAdj(variance);   # Scale it to 8 bit int13    bgList = [0,0,0]               # initialize the color array14    if(variance < 0):15        bgR = 0;                    # too dry, no red16        bgB = adj;                  # green and blue slide equally with adj17        bgG = 255 - adj;1819    elif(variance == 0):             # perfect, all on green20        bgR = 0;21        bgB = 0;22        bgG = 255;2324    elif(variance > 0):             #too wet - no blue25        bgB = 0;26        bgR = adj;                  # Red and Green slide equally with Adj27        bgG = 255 - adj;2829    bgList = [bgR,bgG,bgB]          #build list of color values to return30    return bgList;
复制代码


报告传感器状态则比较简单,直接调用 greengrass SDK 的 publish 函数即可。


由于需要周期性地采集传感器的数据,因此,这个 Lambda 函数需要长时间运行,这里我们利用 threading 的 Timer 实现每 5 秒采集一次传感器数据:


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


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


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


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


 1temp_value = float(event['temp']) 2        mois_value = int(event['moisture']) 3        light_value = int(event['light']) 4        status = int(event['switch']) 5        if mois_value < threshold: 6            if ((light_value > light_threshold) and (temp_value > temp_threshold)):         ##反转模式 7                if status: 8                    state = "off" 9                else:10                    state = "on"11            else:             ## 步进模式12                state = "on-1"13        else:14            if status:15                state = "off"1617        grovepi.pinMode(relay,"OUTPUT")18        if state == "on":           # 反转模式19            try:20                grovepi.digitalWrite(relay,1)21                logger.info("Triggering relay turned ON!")22            except Exception as e:23                logger.error("Failed to switch ON relay: " + repr(e))24        elif state == "on-1":    # 步进模式25            try:26                grovepi.digitalWrite(relay,1)27                logger.info("Triggering relay turned ON - one time!")28                time.sleep(1)29                grovepi.digitalWrite(relay,0)30            except Exception as e:31                logger.error("Failed to switch ON relay[one time]: " + repr(e))32        elif state == "off":33            try:34                grovepi.digitalWrite(relay,0)35                logger.info("Triggering relay turned OFF!")36            except Exception as e:37                logger.error("Failed to switch OFF relay: " + repr(e))38        else:39            logger.info("No need to change!")
复制代码


在编写好 Lambda 函数后,需要将其打包成 zip 文件。打包时,需要注意将 greengrasssdk 目录一起打包到 zip 文件中,greengrasssdk 目录可以从 Amazon Greengrass Core SDK for Python 中获取。打包命令如下:


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


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

  • Runtime 请选择 Python 3.7

  • 对于代码输入种类,请选择上传 zip 文件

  • 对于 Handler(处理程序),分别输入 wfSensorLambda.function_handler 和 wfSwitchLambda.switch_handler

  • 分别上传 wf_sensor_lambda.zip 和 wf_switch_lambda.zip

  • 发布函数后,建议为函数创建别名


为 Amazon 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 不用修改。


配置如下订阅:



针对本文的第二种交互模式,需要在树莓派上修改 Amazon IoT Greengrass 的参数。打开 /greengrass/config/config.json,在 “runtime”部分,增加:


1"allowFunctionsToRunAsRoot" : "yes"
复制代码


在 Amazon IoT 控制台上,在相应 greengrass 组中,点击 Deploy 部署,将云配置部署到树莓派设备。第一次部署可能需要几分钟。当部署完成后,您应该在部署页面上的状态列中看到已成功完成。


您可以验证 Lambda 函数是否在设备上运行,详细步骤参见下方链接。


  • 链接

https://docs.aws.amazon.com/zh_cn/greengrass/latest/developerguide/lambda-  check.html。


创建和配置 Amazon Elasticsearch


在 Amazon Elasticsearch 控制台上,创建一个新域,名称为 waterflower,网络配置选择“Public access”,并输入以下 Access policy(访问策略):


 1{ 2  "Version": "2012-10-17", 3  "Statement": [ 4    { 5      "Effect": "Allow", 6      "Principal": { 7        "AWS": "*" 8      }, 9      "Action": "es:*",10      "Resource": "arn:aws-cn:es:<region>:<your-Account-ID>:domain/waterflower/*",11      "Condition": {12        "IpAddress": {13          "aws:SourceIp": [14            "x.x.x.x/32"15          ]16        }17      }18    }19  ]20}
复制代码


上面“x.x.x.x”请输入您的电脑对应的公网 IP 地址,您可以输入https://checkip.amazonaws.com获得。


访问 Kibana 界面,创建 index,命名为 wf-sensor:


 1PUT /wf-sensor 2{ 3  "mappings": { 4    "properties": { 5      "timestamp": { "type": "long", "copy_to":  "datetime" }, 6      "datetime": { "type": "date", "store": true }, 7      "clientId": { "type": "text" }, 8      "temp":    { "type": "float" }, 9      "moisture":  { "type": "integer"  }, 10      "light":   { "type": "integer"  },11      "switch":  { "type": "integer" },12      "state":  { "type": "integer" }13    }14  }15}
复制代码


创建 index pattern:

  • 名称:wf-sensor*

  • 时间过滤器字段名称:datetime


配置 IoT 规则引擎


在 Amazon 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,您现在可以创建可视化图表,并可以添加到仪表板中,以远程监控和查看传感器状态和继电器/水泵工作情况。如下图示例:



测试和验证


您可以通过以下几个方法验证自动浇花效果:


  • 利用 Amazon IoT 控制台的 test 功能发布消息到 waterflower/setting,修改湿度阈值,测试水泵工作情况

  • 通过 Amazon Elasticsearch 的 Kibana 界面,查看传感器数据变化情况和水泵工作情况

  • 关闭树莓派的互联网连接,验证连接丢失的条件下,自动浇花是否正常工作


资源清理


在您成功搭建了本文介绍的自动浇花系统后,根据您的使用需求,可以按照如下两种情况对创建的资源进行清理,以免产生不必要的费用。


如果您想继续使用自动浇花功能,但不再需要进行远程监控,请按以下步骤删除资源:

  • 打开 Amazon IoT 控制台,依次选择 Act -> Rules,点击之前创建的规则 waterflower 的右上角省略号(…),点击删除并确认

  • 打开 Amazon Elasticsearch 控制台,可以看到之前创建的域 waterflower,点击进入。然后,点击最上面一排的“Delete domain(删除域)”按钮,在弹出窗口中,选中 checkbox 框,然后点击删除


如果您不再使用整个自动浇花系统,请先按上面步骤删除远程监控相关的资源,然后按以下步骤继续清理所有资源:


  • SSH 到树莓派,输入以下命令停止 greengrass 进程:


1$sudo /greengrass/ggc/core/greengrassd stop
复制代码


  • 打开 Amazon IoT 控制台,点击左边菜单栏中的 Greengrass -> Groups,点击之前创建的组 waterflower,进入组管理界面,点击右上角的 Actions -> Reset Deployments,在弹出窗口中,选中 checkbox 框,点击 Reset deployment

  • 接着点击右上角的 Actions -> Delete Group,在弹出窗口中,点击“Yes, Continue to delete”按钮,确认删除

  • 继续在 Amazon IoT 控制台,点击左边的 Manage -> Things,点击 waterflower_Core 的右上角省略号(…),点击删除并确认


小结


根据上面的方案实现,您可能会发现在树莓派系统上运行 Amazon IoT Greengrass 可以构建更多的 IoT 解决方案。从基本的遥测到执行机器学习推理,我们的客户正在构建多种多样的 Amazon IoT Greengrass 解决方案,以便不断创新并扩展解决方案的价值。


在本文中,您学习了如何利用 Amazon IoT Greengrass DIY 一个自动浇花系统。现在,您可以扩展这个方案,增加手机 App 实现对浇花参数控制和远程监控自动浇花工作状况,并利用 Amazon IoT Greengrass 不断改进您的边缘功能。


本篇作者


张红杰

亚马逊云科技解决方案架构师

负责基于亚马逊云科技的云计算方案架构咨询和设计,同时致力于亚马逊云科技物联网服务和无服务器架构在国内和全球商业客户的应用和推广,推进企业服务迁移上云进程。有 10 年以上的数据中心基础架构设计,企业级应用系统设计开发等经验。


用户头像

还未添加个人签名 2019.09.17 加入

还未添加个人简介

评论

发布
暂无评论
利用 Amazon IoT Greengrass 在边缘 DIY 自动浇花系统