简体   繁体   中英

Alerting one time on a reading taken every second Python

I am working on a Raspberry Pi 4B and have a BME680 Air Quality sensor hooked up. My reading are taken every second and written to a MySQL database.

I want to be able to alert if the air quality, temp, etc. gets out of optimal range. The issue I am having is the sensor takes a reading every second so if I try to build an alert it goes off every second until the range is back to optimal. I am wondering how to alert only if the values change outside of a range.

# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

import time
import board
from busio import I2C
import adafruit_bme680
import subprocess
import mysql.connector
from datetime import datetime

#SQL Setup
mydb = mysql.connector.connect(
  host="localhost",
  user="some_user",
  password="some_pass",
  database="some_db"
)
# Create library object using our Bus I2C port
i2c = I2C(board.SCL, board.SDA)
bme680 = adafruit_bme680.Adafruit_BME680_I2C(i2c, debug=False)

# change this to match the location's pressure (hPa) at sea level
bme680.sea_level_pressure = 1013.25

# You will usually have to add an offset to account for the temperature of
# the sensor. This is usually around 5 degrees but varies by use. Use a
# separate temperature sensor to calibrate this one.
temperature_offset = -1

while True:
    now = datetime.now()
    formatted_date = now.strftime('%Y-%m-%d %H:%M:%S')
#    print("\nTemperature: %0.1f C" % (bme680.temperature + temperature_offset))
#    print("Gas: %d ohm" % bme680.gas)
#    print("Humidity: %0.1f %%" % bme680.relative_humidity)
#    print("Pressure: %0.3f hPa" % bme680.pressure)
#    print("Altitude = %0.2f meters" % bme680.altitude)
#    print (formatted_date)
    tmp = (bme680.temperature + temperature_offset)
    real_temp = (tmp * 1.8) + 32
#    print(real_temp)
    gas = (bme680.gas)
    humid = (bme680.relative_humidity)
    pres = (bme680.pressure)
    mycursor = mydb.cursor()
    sql = "INSERT INTO data (Temperature, Gas, Humidity, Pressure, DT) VALUES (%s, %s, %s, %s, %s)"
    val = (real_temp, gas, humid, pres, formatted_date)
    mycursor.execute(sql, val)
    mydb.commit()
##    if ( tmp > 19 ):
##        subprocess.call(['python3', 'alert.py'])
#    else:
#        print ("nothing to do")
    time.sleep(1)

Here is my code. Again I do not want to call my alert.py every second that would over whelm the server I am alerting, I am hoping to alert once when the temp drops below 19 degrees Celsius.

Thank you

You can add a function to get the range in which the temperature is present. If the range has changed, send the alert again. Your state is the range in which your temperature falls.

Please see below:

import bisect
temp_ranges = [15, 20, 25, 30]
temp_states = ['Severe', 'Normal', 'Rising', 'High', 'Gonna Blow up!']

def get_range(temp):
    return bisect.bisect_left(temp_ranges, temp)

for temp in [10, 13, 15, 16, 20, 21, 25, 26, 30, 35]:
    print(f'Temp is: {temp}: Label is {temp_states[get_range(temp)]}')

Then call the function in your while True loop once you have calculated the temperature tmp . Like so:

state = temp_states[get_range(tmp)]
if state is not previous_state:
    subprocess.call(['python3', 'alert.py'])
    previous_state = state # define previous_state = None before your loop begins.
else:
    print ("nothing to do")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM