Laundry Alert!

I had a conundrum.  I was making unnecessary trips down three and a half flights of stairs only to turn around, make the return trip, wait a while, and do it all again.  I could never tell when communal laundry space was in use, nor could I tell whether or not the washer or dryer cycle was finished.  So, having a few Raspberry Pi’s around and an annoying problem to eliminate, I came up with this little guy.

Laundry Alert 1

It has saved me countless, unnecessary trips down to the laundry.  It’s just a raspberry pi, microphone, wifi adapter, a few scripts, Icinga, and Apache.  Put it all together in the right way and you’ve got a lot more free time on your hands… and maybe a bigger belly, if I’m honest.

The OS on the Pi is Raspbian (  I then installed the following packages:

  • icinga
  • apache2
  • openssh-server

The microphone I’m using is available over at Sparkfun.


Icinga might be a little overkill for something as simple as a laundry alert, but it serves its’ purpose very well.  The parts of Icinga that I’m utilizing are the service checks, notification system, and the event/notification handlers.  Another nice feature that you get with Icinga is the complete history of the alerts & availability of the device you’re monitoring.  You can track how many hours per day/month/year the laundry is being used.

Host & Service Definitions

What I’m monitoring is effectively a microphone service, and the host is the Raspberry Pi.  I created a new host definition called “Washer_Dryer” and a new service by the same name.

The host definition:

define host{
 use generic-host
 host_name Washer_Dryer
 alias Washer_Dryer

The service definition:

define service{
 use generic-service
 host_name Washer_Dryer
 service_description Washer_Dryer
 check_command check_noise!30
 check_interval 1
 flap_detection_enabled 0

In the service definition, there’s a line that defines the check_commad to be used.  I’m using a custom command that I made just for this project, called “check_noise”.   Here’s the script:


#Get noise value from read_noise process
noise=`cat /var/lib/check_noise/noise`

# Exit codes

while [ "$1" ]; do
 case "$1" in
 -w | --warning | -c | --critical)
 if [[ -z "$2" || "$2" = -* ]]; then
 # Threshold not provided
 echo "$PROGNAME: Option '$1' requires an argument"
 elif [[ "$2" = +([0-9]) ]]; then
 # Threshold is a number
 # Threshold is not a valid number
 echo "ERROR: Threshold must be valid integer"
 [[ "$1" = *-w* ]] && thresh_warn=$thresh || thresh_crit=$thresh
 shift 2
 echo "ERROR: Invalid option '$1'"

if [ $noise -lt $thresh ]
 echo "OK - Washer/Dryer Not In Use NL:$noise"
 exit $STATE_OK
 echo "CRITICAL - Washer/Dryer In User NL:$noise"

This script is checking a file that contains information about how much noise has been picked up by the microphone.  Depending on the value in the file, the script reports back to Icinga with either OK, WARNING, or CRITICAL by using an exit code.  Depending on the state of the service at the time of the check and what the newly reported state is, Icinga will send out notifications based on the defined notification command for the service.

Notification Command

I configured a special notification command for the contact that I defined for myself, “notify-laundry”.  It’s basically just a CASE statement with an element for each possible state of the service (OK, Warning, Critical, or Unknown).


case "$1" in


 # The service just came back up, we need to tell that world that all's quiet in the Laundry room!
 /usr/bin/printf "%b" "Laundry is now AVAILABLE" | /usr/bin/mail -s "** Laundry Alert **" $2
 echo "<html><body><h1><font size=10 color=green>Laundry is: AVAILABLE</font></h1></body></html>" > /var/www/laundry.html

 # Dont need to do anything

 # Dont need to anything


 # Is this a "soft" or a "hard" state?
 /usr/bin/printf "%b" "Laundry is now IN USE" | /usr/bin/mail -s "** Laundry Alert **" $2
 echo "<html><body><h1><font size=10 color=red>Laundry is: IN USE</font></h1></body></html>" > /var/www/laundry.html


exit 0

For my purposes, I’m not really concerned with the Warning or Unknown states.  I’m only performing an action if the state changes to or from an OK or Critical state.  For either one, the first action is to send out an email alert about what the current state is, then the second action updates an very simple webpage.

 Reading the noise level

If you’ve read the first few lines of the “check_noise” script, you’ll notice that I’m getting noise information form a “read_noise” process.  That’s another little script that I wrote that is constantly running in the background, polling the microphone to determine whether or not there’s noise in the vicinity.


while [ 1 -eq 1 ]

gpio mode 4 in

 while [ $reset -lt 100 ]
 let reset=reset+1
 let noiselevel=noiselevel+$(`echo gpio read 4`)
 #echo $reset
 #echo $noiselevel
 #echo `gpio read 4`

sleep 2
echo $noiselevel > /var/lib/check_noise/noise
#echo `gpio read 4`


The microphone is connected via the GPIO ports, and has a gate output which is able to provide a 0 value for no sound and a value of 1 when there is sound.  I’m polling the gate 100 times, counting up the 1 values, storing the end result in the noise file, waiting 2 seconds, and then repeating,  This is providing me with a measurement of sorts as to how noisy the area is.  This value in conjunction with the thresholds set with the check_noise command is what the alerts are based on.

I have left a lot of configuration and setup details out of this post.  However, I think that there’s enough here that if you wanted to set this up, you could… with an added dose of google.