#!/usr/bin/perl # Monitors the door contacts on a Remote Monitoring System (RMS V1) # see http://www.remotemonitoringsystems.ca/rms/rms.php # the MIBS are at http://www.remotemonitoringsystems.ca/rms/snmp.php # the one we want to monitor is the IO port that is wired to a simple NC magnetic door contact # .1.3.6.1.4.1.21749.1.3.x where x is the io port # # GNU license applies # (C) Alan Madill, amadill --at-- hwy16.com, Jan 2010 # # requires Net::SNMP use Net::SNMP; #Simple network management protocol use Net::SMTP; #Simple mail transport protocol use strict; require 'ctime.pl'; # we could load these from the command line my($target) = "10.1.1.1"; # the IP of the RMS board my($ioport) = "1"; # the IO port the switch is connected to my($debug) = 0; # set to 1 for debugging my($verbose) = 0; # set to 1 for status messages # the oid for the io ports on the RMS my($baseoid) = ".1.3.6.1.4.1.21749.1.3."; my($community) = "public"; # can't be changed on the RMS # where we keep the current state of the door contact my($statefile) = "/root/bin/doorstatus.txt"; # who do we call? my($maillist) = "/root/bin/alarmcontact.txt"; my($mailhost) = "mail.mydomain.com"; # the counter gets incremented from 0 to max when the door is open and then rolls over to 0 again # the alarm message is sent out when the counter is 0 and the door is open # the counter gets reset to 0 when the door makes the transition from open to closed my($max) = 30; # every 30 minutes assuming the cron calls it once a minute my(%state); my($session) = Net::SNMP->session(-hostname => $target, -community => $community); if (! defined($session)) { print "session creation error: ".$session->error."\n" if ($debug || $verbose); exit; } my($oid) = ($baseoid.$ioport); my($result) = $session->get_request($oid); if (! defined($result)) { print "no result returned: ".$session->error."\n" if ($verbose); $session->close; exit; } my($status) = $result->{$oid}; print "IO Status: $status\n" if ($verbose); $session->close; # open up the status file and read it open(STATE, "<$statefile"); while () { chomp; my($a, $b) = split(/\s/, $_, 2); $state{$a} = $b; print "$a:\t$state{$a}\n" if ($debug); } close(STATE); $status = 0 if ($debug); exit if ($status && ($state{door} eq 'closed')); # door is still closed if (! $status && ($state{door} eq 'closed')) { # someone just opened the door! # send the alarm # write the new state $state{door} = 'open'; $state{counter} = 1; writestate(); do_alarm("Door OPEN event at $target"); } if (! $status && ($state{door} eq 'open')) { # the door is still open $state{counter}++; if ($state{counter} == $max) { do_alarm("Door STILL OPEN event after $state{counter} minutes at $target"); $state{counter} = 0; } writestate(); } if ($status && ($state{door} eq 'open')) { # the door just closed $state{counter} = 0; $state{door} = 'closed'; do_alarm("Door CLOSED event at $target"); writestate(); } sub do_alarm { # send the alarm to the list of email addresses my($msg) = shift; print "Message: $msg\n" if ($verbose); my($now) = ctime(time); open(MAIL, "<$maillist") or die "unable to open $maillist\n"; while () { chomp; my($smtp) = Net::SMTP->new($mailhost) or die "unable to open SMTP\n"; $smtp->mail('dooralarm@hwy16.com'); $smtp->to("$_"); $smtp->data(); $smtp->datasend("To: $_\n"); $smtp->datasend("Subject: $msg\n"); $smtp->datasend("$msg\n"); $smtp->datasend("door: $state{door}\n"); $smtp->datasend("time: $now\n"); $smtp->dataend(); $smtp->quit; } } sub writestate { # write the current state to file my($now) = ctime(time); open(STATE, ">$statefile") or die "error opening $statefile\n"; print STATE "door $state{door}\n"; print STATE "counter $state{counter}\n"; print STATE "event $now"; close(STATE); }