I decided that using Icinga for my Laundry Alert device was a little much… It’s an enterprise grade network and service monitoring tool and I was using it to monitor our washer and dryer.
So, I rolled up my sleeves and dug into revamping the whole thing as a Python program. I’m not a programmer by trade, so the code isn’t very pretty, but here it is:
import RPi.GPIO as GPIO
import time
from django.template import Template, Context
from django.conf import settings
import sys
def main():
settings.configure()
# Setting Variable Defaults
# Some of these should be available as cmd line options
webpage = "/var/www/python.html"
threshold = "30"
avgnoise = 0
prev_normalized_noise = 0
fromaddress = "fromaddress@example.com"
toaddress = "alertrecipient@example.com"
# Setting up Raspberry Pi GPIO pins
GPIO.setmode(GPIO.BCM)
GPIO.setup(23, GPIO.IN)
# This is where the fun begins! Loop forever!
while 1:
# Setting variable defaults prior to gathering noise samples from Microphone
samples = 0
noise_sample = []
normalized_noise = 0
# Gather 3 sets of 60 samples, 1 sample every 500ms from microphone
while int(samples) <= 2:
# Setting variable defaults
noise = []
reset = 0
# Get 60 samples of noise data (1/0 = yes/no)
while int(reset) <= 59:
# Append current noise sample value (either 1 or 0) to list from GPIO pin #23
noise.append(GPIO.input(23))
# Write out current sample value
sys.stdout.write(str(noise[reset]))
sys.stdout.flush()
# Incement the counter
reset += 1
# Sleep for 500ms
time.sleep(.5)
# SUM the list of sample values
avgnoise = (sum(noise))
# Print out the SUM of the values
print ""
print "Noise level: %d/%d" % (avgnoise, reset)
# Append the sum of values to the sample list
noise_sample.append(avgnoise)
# Increment the sample counter
samples += 1
# Get the average number or noisey samples (SUM of values divided by number of samples)
normalized_noise = (sum(noise_sample) / len(noise_sample))
# Print out the information
print "Normalized Noise: %d" % normalized_noise
print "Current tooNoisey result: %s" % tooNoisey(normalized_noise, threshold)
print "Previous tooNoisey result: %s" % tooNoisey(prev_normalized_noise, threshold)
# Determine whether the state has change from the last set of samples
# if the state change, we need to send alerts, update webpage, etc
# if not, do nothing
if (tooNoisey(normalized_noise, threshold) and (tooNoisey(prev_normalized_noise, threshold))):
skip = True
elif ((tooNoisey(normalized_noise, threshold) == False) and (tooNoisey(prev_normalized_noise, threshold) == False)):
skip = True
else:
skip = False
print "Are we skipping the alert/webpage update: %s" % str(skip)
if tooNoisey(normalized_noise, threshold) and not skip:
print "---- Laundry is IN USE ----"
print "--Updating status page and sending email alert--"
publishWebpage(webpage, 'red', 'IN USE')
sendEmail(fromaddress, toaddress, 'Laundry is IN USE')
elif not tooNoisey(normalized_noise, threshold) and not skip:
print "---- Laundry is AVAILABLE ----"
print "--Updating status page and sengin email alert--"
publishWebpage(webpage, 'green', 'AVAILABLE')
sendEmail(fromaddress, toaddress, 'Laundry is AVAILABLE')
# The current normalized vaule is now the previous value
prev_normalized_noise = normalized_noise
def tooNoisey(noise, threshold):
if int(noise) >= int(threshold):
return True
if int(noise) < int(threshold):
return False
def sendEmail(me, to, msg):
import smtplib
from email.mime.text import MIMEText
msg = MIMEText(msg)
msg['Subject'] = ''
msg['From'] = me
msg['To'] = to
s = smtplib.SMTP('localhost')
s.sendmail(me, [to], msg.as_string())
s.quit()
def publishWebpage(htmlfile, color, status):
f = open("/home/pi/template.conf",'r')
template = f.read()
f.close()
t = Template(template)
context = Context({"color": color, "status": status})
newpage = t.render(context)
f = open(htmlfile,'w')
f.write(newpage)
f.close()
if __name__ == "__main__":
main()