当传感器有一定水位时,Python会发送电子邮件

2024-05-12 13:41:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用HC-SR01传感器在树莓pi上开发一个应用程序。现在我有一个python脚本,它每秒检查一次水位

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO_TRIGGER = 16
GPIO_ECHO = 18

GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)

def distance():
    # set Trigger High
    GPIO.output(GPIO_TRIGGER, True)

    # set Trigger after 0.1ms low
    time.sleep(0.00001)
    GPIO.output(GPIO_TRIGGER, False)

    startTime = time.time()
    endTime = time.time()

    # store start time
    while GPIO.input(GPIO_ECHO) == 0:
        startTime = time.time()

    # store arrival
    while GPIO.input(GPIO_ECHO) == 1:
        endTime = time.time()

    # elapsed time
    TimeElapsed = endTime - startTime
    # multiply with speed of sound (34300 cm/s)
    # and division by two
    distance = (TimeElapsed * 34300) / 2

    return distance


while True:
    dist = distance()
    print ("Entfernung = %.1f cm" % dist)
    time.sleep(1)

这是工作良好,现在我想给自己发一封电子邮件,然后水位高于一定的限制。电子邮件的发送不是问题,而是何时发送的逻辑。 如果我在while循环中放入sendmail()函数,当水位达到时,我会每秒收到一封电子邮件。所以下面的人不会这么做:

#global varaible
alarm_waterlevel = 170

#in while loop
if dist > alarm_waterlevel
  sendMail()

因此,我正在寻找一个聪明的解决方案,只在水位达到时发送邮件

我在考虑一个全局变量,在再次触发邮件之前检查水位是否下降到某个点以下。大概是这样的:

#global varaible
alarm_waterlevel = 170
mail_sent = false

#in while loop
if dist >= alarm_waterlevel && mail_sent == false
  sendMail()
  mail_sent = true
if dist <= alarm_waterlevel - 10
  mail_sent = false

您认为这是一个容错解决方案吗?有什么好的建议可以帮我解决这个问题吗


Tags: echogpioiftimedistmailsentdistance
2条回答

我认为你的if语句中有一个普遍的逻辑问题。 当距离大于或等于您的警报级别时,您希望发送电子邮件。 我认为您的超声波传感器从上到下测量,因此您的if声明应为:

size_water_container = 200 #Just a estimadet value
if dist < (size_water_container - alarm_waterlevel) and waterlevel_before > (size_water_container - alarm_waterlevel):
    sendMail()

如果我错了,那就忽略它:) 但现在谈谈你的问题。 如果永久性地查询距离,则必须在之前永久性地保存水位,但不保存在If语句中。以后再做就行了

alarm_waterlevel = 170
size_water_container = 200
waterlevel_before = 0
while True:
    dist = distance()
    if dist < (size_water_container - alarm_waterlevel) and waterlevel_before > (size_water_container - alarm_waterlevel):
        sendMail()
    waterlevel_before = dist
    time.sleep(1)

对于覆盆子Pi解决方案,您的方法在我看来是合理的;)

您可以考虑的另一件事是添加三种不同的警告级别或系统可能处于的状态

L1: send once, 80% full
L2: send every 5 minutes, 90 % full
L3: send every minute, > 100 % 

你必须考虑什么时候改变状态。你可以加上一些类似磁滞的东西。这可能是优雅的,所以你不必使用三个不同的高度级别

如果水位升高,您可以切换该状态,例如在80%时,但只有在水位低于70%时才切换回较低的警告状态。这个想法是,当水位在78%到82%之间时,系统不会不断改变状态

你可以想到的另一件事是通过观察水位的导数(一阶或二阶)来进行投影。然后,当水位快速上升但仍低于临界阈值时,您可以提前发出警告

相关问题 更多 >