基于行空板的智慧农业网页系统
本帖最后由 IvanDMido 于 2022-5-8 23:49 编辑智慧农业网页系统前言这个项目被砍了,emmmm,那就简化后悄悄发在这儿吧,留个纪念。
项目背景课堂教学场景下的智慧农业项目最先是这样的:利用一块单片机(microbit/掌控板?)结合几个传感器(土壤湿度、光线等)来采集数据,之后将数据显示出来(GUI界面或IDE终端)并对它进行判别,当数值不佳时自动改善环境(浇水、补光等)。这里主要通过它的自动化来体现所谓的“智慧”。
之后,随着物联网技术的发展,借助以MQTT为底层技术的物联网平台(SIoT/EasyIoT等),我们可以将传感器检测到的数据存放到平台上,随后在服务器的网页端远程直观地查看数据记录,将数据以图表形式(折线图)呈现出来,将数据导出进行数据分析,甚至在平台网页端远程发送消息通过手动控制来实现浇水、补光等功能。这里,数据呈现形式的清晰化及功能的全面性(远程查看并控制)极大得丰富了项目的课堂效果,也提升了真实性。
然而,用多了我们会发现,它还是有些许不足之处的,比如,服务器网页端页面结构的固定化、数据呈现方式的固定化、图表样式的的单一化,等等。
那么,有没有什么工具能在保留物联网系统的优点的同时,还能让页面呈现的方式更加多样化,或者能让我们自己设计页面数据的呈现方式呢?
项目目标这个项目中,我们将借助Python的PyWebIO库来自主设计并开启一个网页服务,在页面上呈现通过传感器检测到的土壤湿度值和光线值,并在数值不佳时以弹窗的形式进行提醒,同时,可通过页面上的按钮来控制浇水等功能。材料清单硬件清单:理论上需要:行空板、USB数据线、土壤湿度传感器、两头PH2.0-3P白色硅胶绞线、12V/1000mA 电源适配器、简易继电器模块、带水管潜水泵
实际上:没有传感器、执行器硬件怎么办?那就不用了吧,有行空板即可,不影响实验效果的模拟。
软件使用:Mind+编程软件x1
其他:1、带植物的花盆 x12、盛有水的烧杯 x13、十字/一字两用螺丝刀 x1
知识储备1、行空板简介:这个不介绍了。还是说两句吧。行空板是一块有趣的板子,它是单片机系统和单板机系统的集合体。单片机系统类似一块Arduino/micro:bit,各种常见传感器、执行器(加速度计、蜂鸣器、按键等等)都接在了单片机上;单板机类似一台小电脑,上面有触摸显示屏、USB口、麦克风等等。这个项目中我们会用到行空板上面内置的WiFi蓝牙天线(连接网络)、光线传感器(检测光线值)、扩展接口(外接土壤湿度传感器检测数值)。Tips:要是对板子感兴趣,可以看看相关的Wiki和详细教程介绍。行空板官方WiKi文档:wiki.unihiker.com
2、Pinpong库简介:这个真不介绍了,它是一套用来控制开源硬件的Python库。Pinpong库官方文档:https://pinpong.readthedocs.io/zh_CN/latest/
3、PyWebIO库介绍:传统的网站开发需要通过前端和后端的交互配合来实现。前端负责网页页面的版式布局等,后端负责提供服务数据接口、逻辑功能等。因此,要想实现网站页面的设计,我们需要学习多方面的知识。比如前端中涉及到的html和css外加一些js等一些样式的布局,后端中涉及的数据库、服务器技术等等。
听起来很复杂,那有没......肯定有的。
与传统相对,PyWebIO是一个用于在浏览器上获取输入和进行输出的工具库。能够将原有的通过终端交互的脚本快速服务化,供其他人在网络上通过浏览器访问使用; PyWebIO还可以方便地整合进现有的Web服务,让你不需要编写Html和JS代码,就可以构建出具有良好可用性的Web程序。特点:l 使用同步而不是基于回调的方式获取输入,无需在各个步骤之间保存状态,使用更方便l 代码侵入性小,对于旧脚本代码仅需修改输入输出逻辑l 支持多用户与并发请求l 支持结合第三方库实现数据可视化l 支持整合到现有的Web服务,目前支持与Flask、Django、Tornado、aiohttp框架集成l 同时支持基于线程的执行模型和基于协程的执行模型
简单来说,最大的特点便是,这个库可以将让你通过简单的函数指令一边设计页面布局,一边将数据呈现出来。
PyWebIO库中文文档:Https://pywebio.readthedocs.io/zh_CN/latest/guide.html
4、HTTP超文本传输协议与MQTT消息队列遥测传输协议简介:略MQTT官方文档:https://siot.readthedocs.io/zh_CN/latest/1.about/02_mqtt.html
动手实践任务描述:在网页上显示传感器实时采集到的数据以及通过页面按钮控制输出1、硬件搭建
STEP1:通过USB连接线将行空板连接到计算机
STEP2:手机开个热点,行空板联网打开浏览器,输入“10.1.2.3”,进入行空板网页菜单,这里可以设置板子的网络连接。
Tips:下面几个步骤没有硬件的可以忽略。STEP3:将土壤湿度传感器接入行空板的P21引脚,将继电器接入行空板的P23引脚
STEP4:将土壤湿度传感器插入花盆中STEP5:利用螺丝刀将水泵正负线与转接头连接起来。STEP6:利用继电器将12V电源开关与水泵的转接头连接起来STEP7:将继电器开关拨至NO端STEP8:将水泵固定在满水的烧杯中STEP9:将水管插入花盆中
2、程序编写STEP1:创建与保存项目文件启动Mind+,另存项目并命名为“010、智慧农业网页系统”。
STEP2:创建与保存Python文件创建一个Python程序文件“main.py”,双击打开。
STEP3:导入图片文件夹在项目文件夹中导入背景图文件夹。(图片文件夹与程序文件同在项目文件夹中,附录有all)
STEP4:程序编写(1) 导入所需功能库Pinpong库用来控制硬件,pywebio库start_server模块用来开启网页服务,pywebio库output模块用来在页面输出呈现内容,datetime模块用来获取时间。
from pinpong.board import Board, Pin, ADC # 从pinpong.board包中导入Board, Pin, ADC模块
from pinpong.extension.unihiker import * # 导入pinpong.extension.unihiker包中所有模块
from pywebio import start_server # pywebio to provide the PyWebIO application as a web service
from pywebio import output# to obtain user input content
import time# python's time module
import datetime# python's datetime module(2) 初始化板子和引脚
Board().begin()# 初始化行空板
adc0 = ADC(Pin(Pin.P21, Pin.IN))# 初始化21引脚为模拟输入模式
relay = Pin(Pin.P23, Pin.OUT)# 初始化23引脚为数字输出模式(3) 定义页面上两个按钮的功能当按钮A被点击后,继电器输出高电平,进行浇水,页面显示一个提示“浇水”的小弹窗,一秒后弹窗关闭。按钮B同理,继电器输出低电平,用来停止浇水。<font face="微软雅黑" size="2">'''定义按钮A、B的功能'''
def button_A():
"""浇水 button andpopoup message 浇水 when clicked"""
relay.value(1) # 继电器输出高电平,浇水
output.popup('提示', '浇水', size=output.PopupSize.SMALL) # 输出显示一个提示弹窗
time.sleep(1) # delay 1 second
output.close_popup() # close弹窗
def button_B():
"""关水 button andpopoup message 关水 when clicked"""
relay.value(0) # 继电器输出低电平,关水
output.popup('提示', '关水', size=output.PopupSize.SMALL) # 输出显示一个提示弹窗
time.sleep(1) # delay 1 sec
output.close_popup() # close弹窗</font>
(4) 定义在网页上显示数值的函数这里,我们在网页上画一个表格,然后将“检测对象”、“数值”、“监测时间”、“数值占比”分别呈现在表格中,其中数值占比以进度条的形式体现,之后在表格下方放两个按钮,用来控制继电器浇水和关水,同时在这里,我们对监测到的数据进行判别,当土壤湿度值过低时在网页上显示一秒弹窗警报。
<font face="微软雅黑" size="2">'''定义一个显示数值的函数'''
def display_value():
"""display value of the sensors on the browser"""
while True:
# open or enter a new output scope, or enter an existing output scope
with output.use_scope(name='time', clear=True):
now1 = datetime.datetime.now()# get the current local date.
now2 = now1.strftime("%Y-%m-%d %H:%M:%S")
Soil_moisture_value = adc0.read() # read土壤湿度传感器的模拟值并用变量Soil_moisture_value存储
# check soil moisture value
if Soil_moisture_value < 50: # 土壤湿度值<50时自动显示弹窗提示
# pop up message
output.popup('提示', '请浇水', size=output.PopupSize.SMALL) # 输出显示一个提示弹窗
time.sleep(1)# pop up for 1 sec and disappear
output.close_popup()# close the pop up after 1 sec
# 输出显示一个表格
output.put_table([# progress bar of the sensors\
# headers of the table, scoep and position
['监测对象', '数值', '监测时间', '数值占比'],
# read soil moisture sensor
['土壤湿度:', output.put_text(adc0.read()), now2, output.put_processbar('土壤湿度')],
# read light
['光线强度:', output.put_text(light.read()), now2, output.put_processbar('光线强度')],
])
# process bar for soil sensor
output.set_processbar('土壤湿度', (adc0.read())/4095)
# process bar for light sensor
output.set_processbar('光线强度', (light.read())/4095)
# buttons for 浇水 and 关水
output.put_buttons(['浇水', '关水'], onclick=)
time.sleep(5)# refreshes the sensor value every 5 seconds</font>(5) 定义一个app函数之后,我们定义一个app函数显示主页的内容。这里,我们首先设置一个标题,之后输出显示一张图片,最后调用之前的数值显示函数,将它放在主页面上。<font face="微软雅黑" size="2"># 定义一个函数显示主页
def app():
"""pywebio application"""
output.put_markdown('## 环境数据监控系统')# title of the application # 输出显示markdown格式标题
img = open('img/tree.png', 'rb').read()# image path used for the app # 打开图片
# settings of the image
output.put_image(img, height='100px', width='90px') # 输出显示图片
display_value() # 调用数值显示函数</font>(6) 启动网页服务最后,我们设置函数app为要启动的主页即可,并设置端口号8078。<font face="微软雅黑" size="2">#Start a server to provide the PyWebIO application as a web service.
start_server(app, port=8078, debug=True) # 启动网页服务</font>
Tips:完整示例程序如下:
<font face="微软雅黑" size="2">#!/usr/bin/python
# -*- coding: UTF-8 -*-
# import libraries
from pinpong.board import Board, Pin, ADC # 从pinpong.board包中导入Board, Pin, ADC模块
from pinpong.extension.unihiker import * # 导入pinpong.extension.unihiker包中所有模块
from pywebio import start_server # pywebio to provide the PyWebIO application as a web service
from pywebio import output# to obtain user input content
import time# python's time module
import datetime# python's datetime module
# import threading# python's threading module
# import os
# cwd = os.getcwd() # get the current working directory
Board().begin()# 初始化行空板
adc0 = ADC(Pin(Pin.P21, Pin.IN))# 初始化21引脚为模拟输入模式
relay = Pin(Pin.P23, Pin.OUT)# 初始化23引脚为数字输出模式
'''定义按钮A、B的功能'''
def button_A():
"""浇水 button andpopoup message 浇水 when clicked"""
relay.value(1) # 继电器输出高电平,浇水
output.popup('提示', '浇水', size=output.PopupSize.SMALL) # 输出显示一个提示弹窗
time.sleep(1) # delay 1 second
output.close_popup() # close弹窗
def button_B():
"""关水 button andpopoup message 关水 when clicked"""
relay.value(0) # 继电器输出低电平,关水
output.popup('提示', '关水', size=output.PopupSize.SMALL) # 输出显示一个提示弹窗
time.sleep(1) # delay 1 sec
output.close_popup() # close弹窗
'''定义一个显示数值的函数'''
def display_value():
"""display value of the sensors on the browser"""
while True:
# open or enter a new output scope, or enter an existing output scope
with output.use_scope(name='time', clear=True):
now1 = datetime.datetime.now()# get the current local date.
now2 = now1.strftime("%Y-%m-%d %H:%M:%S")
Soil_moisture_value = adc0.read() # read土壤湿度传感器的模拟值并用变量Soil_moisture_value存储
# check soil moisture value
if Soil_moisture_value < 50: # 土壤湿度值<50时自动显示弹窗提示
# pop up message
output.popup('提示', '请浇水', size=output.PopupSize.SMALL) # 输出显示一个提示弹窗
time.sleep(1)# pop up for 1 sec and disappear
output.close_popup()# close the pop up after 1 sec
# 输出显示一个表格
output.put_table([# progress bar of the sensors\
# headers of the table, scoep and position
['监测对象', '数值', '监测时间', '数值占比'],
# read soil moisture sensor
['土壤湿度:', output.put_text(adc0.read()), now2, output.put_processbar('土壤湿度')],
# read light
['光线强度:', output.put_text(light.read()), now2, output.put_processbar('光线强度')],
])
# process bar for soil sensor
output.set_processbar('土壤湿度', (adc0.read())/4095)
# process bar for light sensor
output.set_processbar('光线强度', (light.read())/4095)
# buttons for 浇水 and 关水
output.put_buttons(['浇水', '关水'], onclick=)
time.sleep(5)# refreshes the sensor value every 5 seconds
# 定义一个函数显示主页
def app():
"""pywebio application"""
output.put_markdown('## 环境数据监控系统')# title of the application # 输出显示markdown格式标题
img = open('img/tree.png', 'rb').read()# image path used for the app # 打开图片
# settings of the image
output.put_image(img, height='100px', width='90px') # 输出显示图片
display_value() # 调用数值显示函数
# t = session.threading.Thread(target=screen_value)
# session.register_thread(t)
# t.start()
#Start a server to provide the PyWebIO application as a web service.
start_server(app, port=8078, debug=True) # 启动网页服务
</font>3、程序运行
STEP1:将12V电源开关插上220V电源插座(没有硬件忽略)
STEP2:远程连接行空板,运行程序
STEP3:观察终端出现下列界面说明网页服务已成功启动。
STEP4:打开网页查看效果打开手机浏览器,输入上面终端内提示的地址“192.168.43.201:8078”,可以看到我们设计的数据监控系统的页面呈现在眼前,并且每隔五秒刷新一次页面更新数据。而当我们点击“浇水”和“按钮”后,页面内也有相应的弹窗提示,如果成功外接了继电器,还会看到水泵开始抽水工作。Tip1:“192.168.43.201”为我的热点手机的IP,每个手机不一样,视实际情况而定。Tip2:由于手头只有裸板,因此土壤湿度读到的数值巨大(假值),远超过我们设定的阈值“50”,此时无法呈现警报弹窗的效果。
同样地,我们也可以在电脑的浏览器中输入网址打开网页,不过须将电脑网络也连接在热点手机下。
小结1、项目小结这个项目中,我们模拟设计了一个智慧农业网页系统,通过传感器来检测植物生长环境中土壤湿度值和光线值,并将数据呈现在自主设计的网站主页上,从而能够方便得在家中通过网页远程监测农作物的生长,并且通过网页按钮远程对植物进行补水。
2、编程知识小结主要还是库中各函数方法的使用,具体的用法,可查看官方文档(多数函数都有Demo)。PyWebIO库中文文档:Https://pywebio.readthedocs.io/zh_CN/latest/guide.html1、output模块popup()方法输出显示一个弹窗2、output模块close_popup()方法关闭弹窗3、output模块put_table()方法输出显示表格4、output模块put_text()方法输出显示文字5、output模块put_processbar()方法输出显示进度条6、output模块set_processbar()方法设置进度条7、output模块put_buttons()方法输出显示多个按钮8、output模块put_markdown()方法输出markdown格式标题9、output模块use_scope()方法控制内容输出的位置10、output模块put_image()方法输出显示图片11、start_server()函数启动网页服务
挑战自我这里,我们只是用了PyWebIO库的冰山一角,随便设计并开启了一个网页服务,在页面上显示了一下标题、文字、图片、进度条、表格、按钮、弹窗等。如果你坚持看到了这里,不妨来一起思考一下:(-1)如果既没有硬件,又没有行空板,这个项目还能做吗?Tips:在这个项目中,我们借助行空板的单片机系统来采集了数据,又借助了它内置的网卡来连接网络,然后通过编程开启了网页服务。因此本质上,你只要有一台能联网的电脑就能设计网页并在其上显示一些内容了,而如果你手上有micro:bit或者其他单片机,可以用它来采集数据,然后呈现在页面上。不过对于相关的库,需要手动pip install来安装(行空板的固件中已内置了PyWebIO库故无需手动安装)。
(0)有什么办法能仅刷新显示数值而非刷新整个网页呢?Tips:略,自己来试一试吧!
(1)在网页上如何将数据绘制成各种图表显示出来了呢,就像SIoT服务器网页端的折线图?Tips:可以试试PyWebIO中第三方库的数据可视化功能。
(2)行空板本身的2.8寸彩屏是一大特色,我们是否可以将数据发送到网页的同时在板子的屏幕上也显示出来呢?Tip1:这里或许需要采用多线程的方式。Tip2:Python的threading模块、PyWebIO库中的session模块下register_thread方法以及行空板Unihiker库(屏幕控制)下皆有实现多线程的方式。
(3)在使用行空板上内置的SIoT服务搭建物联网系统时(板子本身作为服务器),我们将通过传感器检测到的数据发送到物联网平台后,是否可以再从平台获取,然后应用到我们自己设计的网页上呢?SIoT与PyWebIO间数据的联系该如何打通?Tips:当数据繁琐不便时,或许可以考虑借助数据库(如轻量式的sqlite)。当然首先需要订阅接收Topic下的数据然后调整好它的字符格式。
(4)在使用3块行空板搭建物联网系统时(板1开启SIoT服务和热点作为服务器,板2和板3作为客户端连在它的热点下,通过传感器检测数据并发送给板1服务器),此时,要想在板3上再起一个PyWebIO网页服务,显示板1和板2发来的数据,又该如何实现呢,原理和上述(3)是否相通呢?接着,如果再想给板3添加一个警报发邮件功能(SMTP),该如何实现呢?
(5)内网穿透技术在这样的衍生项目中会有什么使用空间吗,场景可能是怎样的呢?
(6)就先这样吧......
最后如果你又坚持看完了上述碎碎念,那么恭喜,此文终于要结束了,希望它能给你引来一些独立思考。如果你对其中涉及的任何技术感兴趣,欢迎自己作进一步研究,并将你的成果开源出来。最后,特别感谢一下PyWebIO库的开发者成员,以及在原版“智慧农业网页系统”项目中一起研讨和提供help的小伙伴们。
题外话想起了几年前在外滩听罗胖子的跨年演讲,有句话令人印象深刻,他说,“我其实知道,你们哪里是来听什么演讲的,你们无非是想在时间的长河当中给自己找一个时间的标识,这是你们独特的跨年方式。” 那么,就让此文来纪念一下这段一天三捅(两次抗原一次核酸)的“难忘”日子吧,愿各地疫情早日结束,生活回归正常! 2022年5月8日上海宝山 上海加油 漂亮,这个是可以搞个监控大屏了,电脑手机都能看,搞个内网穿透的话哪里都能远程访问了 满心收藏,谢谢
页:
[1]