树莓派,Python和室内植物浇水

我和室内植物没有关系。事实是我忘了给他们浇水。知道了这一点,我开始反思一个事实,肯定有人已经找到了使灌溉自动化的方法。事实证明,有很多方法。即,我们正在谈论基于Arduino或Raspberry Pi的解决方案。在本文中,我想谈谈如何创建基于Raspberry Pi和Python的系统,该系统旨在自动给植物浇水。



组件和有用的资源


我要立即指出,我根本不是电子专家。如果他们要我画电路,或详细说明电子元件的工作原理,我将无法画出任何明智的东西。实际上,我只用电的基本知识就做过这个项目,而只是试验组件。我要求您在使用电时要非常小心。而且,如果您觉得这方面的知识不足,我建议至少对此有所了解。

这是我在项目中使用的组件的列表。


我参加了亚马逊会员计划,因此提供了上面的链接。如果您通过他们买东西,我会赚点钱。

在获得所需的所有组件之后,该进行一些研究了。以下是可帮助我正确连接电子组件并了解其功能要点的资源列表:


这是Raspberry Pi的GPIO端口的示意图。


Raspberry Pi GPIO端口图

将继电器连接到Raspberry Pi


我首先将继电器连接到Raspberry Pi。这是它的外观。


将继电器连接到Raspberry Pi上,

红色导线(母-母)从JD_VCC继电器板的引脚连接到Raspberry Pi的5V引脚(2号引脚)。橙色线(母-母)从VCC继电器板的引脚连接到Raspberry Pi的3.3V引脚(1号引脚)。


继电器板的JD_VCC和VCC引脚

使用这些电线,我们为继电器板供电。为了能够控制单个继电器,您需要使用另外两根线将继电器板和Raspberry Pi连接起来,这些线分别连接到继电器板的GND和IN1引脚。


中继板的GND引脚和IN1母

(母)母线是连接中继板的GND引脚和Raspberry Pi的接地端子(我将其连接到34号引脚)的接地电缆。白线(母-母)从继电器板的IN1引脚连接到Raspberry Pi的12号引脚。正是这条白线使我们能够以编程方式控制继电器,打开和关闭板上的各个继电器。


连接到Raspberry Pi的黑白电线

如果您决定重现我的项目,则可以安排中继和Raspberry Pi使用任何合适的引脚进行通信。但是请记住,如果项目的组件的连接图与项目的组件的连接图不同,则必须对我的代码进行适当的更改。

将电源连接到继电器


将继电器板连接到Raspberry Pi后,将电源连接到其中一个继电器。

在完成所有系统组件收集操作之前,请勿将电源插头插入电源插座。注意电击危险。


将电源连接到一个继电器上

我使用 12V电源附带一个适配器,可以方便地将连接线连接到该适配器上。我将红色电线(公-公)连接到适配器“ +”连接器,将棕色电缆(公-公)连接到适配器“-”连接器。然后,我将带有“鳄鱼”(母-公)连接器的电缆连接到棕色电线。


电源随附的适配器

继电器板上有四个单独的继电器。它们每个都有三个可以连接电缆的插针。每个继电器的中心是一个连接器,外部电源的正输出连接到该连接器。左侧是连接器,要连接电源的设备的正极输入连接到该连接器。


连接单独的继电器

我将红色电缆从电源(正极)连接到继电器的中心触点。然后,我将橙色电缆(公-公)连接到继电器的左侧连接器,并将电缆与“鳄鱼”(母-公)连接到该电缆。


红色和橙色电缆


电源和适配器


中继和Raspberry Pi

将水泵连接到继电器


现在,仅需将连接器“鳄鱼”连接到水泵即可。它们的连接顺序决定了水流的方向。

因此,我需要水进入泵的左通道并离开右通道。因此,我将黑线的“鳄鱼”连接器连接到泵端子(附近有一个红点),将另一个“鳄鱼”连接到另一个泵端子。如果我以不同的顺序连接“鳄鱼”,则水会从右通道向左流向相反的方向。


将水泵连接到继电器


完善的灌溉系统:水通过左侧通道进入泵,从右侧通道离开,然后流至工厂

编码


所以我们做到了我真正擅长的。我们到了代码。为了使软件能够与Raspberry Pi的GPIO端口配合使用,我使用了gpiozero。它易于使用,对程序员隐藏了许多底层机制,对于那些想使用GPIO引脚的人来说,通常需要了解这些机制。该图书馆有据可查。

在编写代码之前,您需要将监视器,鼠标和键盘连接到Raspberry Pi。或者您需要通过SSH连接到Raspberry Pi

输入Raspberry Pi后,转到文件夹Desktop并在其中创建一个文件夹run。在此文件夹中创建一个文件夹classes。然后在文件夹中classes创建一个文件Hardware.py。它应该具有以下代码:

from gpiozero import OutputDevice

class Relay(OutputDevice):
    def __init__(self, pin, active_high):
        super(Relay, self).__init__(pin, active_high)

在此文件中,我刚刚声明了一个新类Relay,它是OutputDevice类的后代

接下来,在文件夹中,classes我创建了一个新文件TimeKeeper.py

import datetime

class TimeKeeper:
    def __init__(self, current_time):
        self.current_time = current_time
        self.time_last_watered = None
    
    def set_current_time(self, updated_time):
        self.current_time = updated_time

    def set_time_last_watered(self, updated_time):
        self.time_last_watered = updated_time

    @staticmethod
    def get_current_time():
        now = datetime.datetime.now()
        return now.strftime("%I:%M:%S %p")

此类的目的是跟踪当前时间和上次浇水的时间。

因此,文件Hardware.pyTimeKeeper.py位于文件夹中classes现在,在此文件夹之外,我创建了一个文件water_plant.py

from classes import Hardware
from classes import TimeKeeper as TK
import schedule
import smtplib
import time
import ssl

# WATERING_TIME must be in "00:00:00 PM" format
WATERING_TIME = '11:59:50 AM'
SECONDS_TO_WATER = 10
RELAY = Hardware.Relay(12, False)
EMAIL_MESSAGES = {
    'last_watered': {
        'subject': 'Raspberry Pi: Plant Watering Time',
        'message': 'Your plant was last watered at'
    },
    'check_water_level': {
        'subject': 'Raspberry Pi: Check Water Level',
        'message': 'Check your water level!',
    }
}

def send_email(time_last_watered, subject, message):
    port = 465
    smtp_server = "smtp.gmail.com"
    FROM = TO = "YOUR_EMAIL@gmail.com"
    password = "YOUR_PASSWORD"

    complete_message = ''
    if time_last_watered == False:
        complete_message = "Subject: {}\n\n{}".format(subject, message)
    else:
        complete_message = "Subject: {}\n\n{} {}".format(subject, message, time_last_watered)
    
    context = ssl.create_default_context()
    with smtplib.SMTP_SSL(smtp_server, port, context=context) as server:
        server.login(FROM, password)
        server.sendmail(FROM, TO, complete_message)

def send_last_watered_email(time_last_watered):
    message = EMAIL_MESSAGES['last_watered']['message']
    subject = EMAIL_MESSAGES['last_watered']['subject']
    send_email(time_last_watered, subject, message)

def send_check_water_level_email():
    message = EMAIL_MESSAGES['check_water_level']['message']
    subject = EMAIL_MESSAGES['check_water_level']['subject']
    send_email(False, subject, message)

def water_plant(relay, seconds):
    relay.on()
    print("Plant is being watered!")
    time.sleep(seconds)
    print("Watering is finished!")
    relay.off()

def main():
    time_keeper = TK.TimeKeeper(TK.TimeKeeper.get_current_time())
    if(time_keeper.current_time == WATERING_TIME):
        water_plant(RELAY, SECONDS_TO_WATER)
        time_keeper.set_time_last_watered(TK.TimeKeeper.get_current_time())
        print("\nPlant was last watered at {}".format(time_keeper.time_last_watered))
        # send_last_watered_email(time_keeper.time_last_watered)

# schedule.every().friday.at("12:00").do(send_check_water_level_email)

while True:
    # schedule.run_pending()
    time.sleep(1)
    main()

在这里您可以更改变量WATERING_TIMESECONDS_TO_WATER看起来合适的变量的值。第一个变量确定什么时候给植物浇水。第二个设置浇水的持续时间。

另外,我在这里创建了一种通过电子邮件发送通知和提醒的机制。由于这种机制,每次打开灌溉系统并浇灌植物时,灌溉系统的所有者都会收到一封电子邮件。此外,每个星期五他都会收到一封信,提醒他,他需要检查灌溉水的供应。在代码中,注释了对相应方法的调用,因此,该程序可以正常运行而无需进行与电子邮件有关的设置。如果要启用这些提醒,请执行以下操作:

  1. 您必须输入该行FROM = TO = «YOUR_EMAIL@gmail.com»以及password = «YOUR_PASSWORD»您的Gmail电子邮件地址和密码。
  2. 取消注释以下行:

    •  #send_last_watered_email(time_keeper.time_last_watered)
    • #schedule.every()。friday.at(“ 12:00”)。做(send_check_water_level_email)
    • #schedule.run_pending()
  3. 您需要转到此处,登录到您的Gmail帐户,然后打开此页面上的开关。否则,当您尝试使用Gmail发送电子邮件时,您会收到一条错误消息。 

此外,请务必注意,我的提醒系统仅适用于Gmail帐户。

现在一切都准备就绪,您应该获得文件和文件夹的以下结构:

run
├── classes
│ ├── Hardware.py
│ └── TimeKeeper.py
└── water_plant.py

文件夹run实际上可以放置在任何地方。我决定将其保留在文件夹中Desktop

每次我必须启动Raspberry Pi时,我都不会被它的前景所吸引water_plant.py我希望该脚本在Raspberry Pi打开时自动运行。例如,这将使关闭系统,将其移动到另一个位置,打开它变得很容易,而不必担心任何事情。为了实施这种有吸引力的方案,我们需要一个团队crontab

在Raspberry Pi上打开终端窗口,然后输入以下命令:

sudo crontab -e

作为响应,系统应输出类似于下图所示的内容。


配置cron任务

在此文件中添加以下行:

@reboot python3 /home/pi/Desktop/run/water_plant.py

然后,必须使用组合键Ctrl+X通过输入Y并按来保存此文件Enter

在上面的行中,我们为Raspberry Pi提供以下指示:“每次重新启动时,运行water_plant.py位于文件夹run中的文件夹中的文件Desktop。” 如果您的文件夹run位于其他位置,请相应地编辑此命令。

摘要


此处查看项目代码如果需要,可以使用以下命令立即克隆存储库:

git clone https://github.com/AlanConstantino/rpi-plant-project.git

就这样!现在,您知道了如何基于Raspberry Pi为室内植物创建自动灌溉系统。她知道每24小时要浇水的方法,并且可以向所有者发送电子邮件通知和提醒。

亲爱的读者们!您将如何开发家庭自动化的植物浇水系统?


All Articles