Page 1 of 1

SNMP Monitoring Box

Posted: Tue Feb 19, 2013 3:14 pm
by gridrun
I'm using the Pi -together with the PiFace Digital- to monitor the environment at various co-location sites for several parameters, and generate SNMP traps accordingly:

- DIESEL generator engaged
- DIESEL generator fault
- MAINS power lost
- A/C unit 1 fault
- A/C unit 2 fault
- Temperature alert

To do so, I wrote a small python program (my "hello world" in python...hehe :geek: )

Code: Select all

#!/usr/bin/env python

print "PiFace SNMP Monitor (c) 2013 by Chris <gridrun> Burri @ Total Optical Networks AG"

# configuration
tempalert = 40.0
sendtrap = "/home/pi/piface/python/piface/"
readtemp = "/home/pi/piface/python/piface/"
msgdieselengaged = "Diesel engaged"
msgdieseldisengaged = "Diesel disengaged"
msgdieselfault = "Diesel fault"
msgdieselclear = "Diesel fault cleared"
msgmainsfault = "Mains power lost"
msgmainsclear = "Mains power restored"
msgac1fault = "A/C unit 1 fault"
msgac1clear = "A/C unit 1 fault cleared"
msgac2fault = "A/C unit 2 fault"
msgac2clear = "A/C unit 2 fault cleared"
msgtempalert = "Temperature alert"
msgtempclear = "Temperature normal"

# imports
from time import sleep
from subprocess import call
import time
import threading
import subprocess
import signal
import sys
import piface.pfio as pfio

# variable definitions
false = 0
true = 1
CurTemp = 0.0
staTempHigh = 0
lstTempHigh = 0
pinDieselRunning = 0
lstDieselRunning = 0
pinDieselFault = 0
lstDieselFault = 0
pinMainsLost = 0
lstMainsLost = 0
pinAirCondition1Fault = 0
lstAirCondition1Fault = 0
pinAirCondition2Fault = 0
lstAirCondition2Fault = 0

# Ctrl-C handler
def signal_handler(signal, frame):
        print "Ctrl-C received; aborting..."

# parameter monitoring function
def parmon(curPar, lstPar, MsgAlert, MsgClear):
        if (curPar != lstPar):
                if (curPar == 1):
                        print "TRAP: " + MsgAlert
                        call([sendtrap, MsgAlert])
                        print "TRAP: " + MsgClear
                        call([sendtrap, MsgClear])

# temperature reader class
class TmpRdrCls(threading.Thread):
        def __init__(self):
                self.event = threading.Event()

        def run(self):
                while not self.event.is_set():
                        global CurTemp
                        global staTempHigh
                        global tempalert
                        proc = subprocess.Popen(["sudo", readtemp], stdout=subprocess.PIPE)
                        CurTemp = proc.stdout.readline()
                        if float(CurTemp) > tempalert:
                                staTempHigh = 1
                                staTempHigh = 0
                        self.event.wait( 18 )

        def stop(self):

# setup temp reader class
tmprdr = TmpRdrCls()
signal.signal(signal.SIGINT, signal_handler)

# initialize PiFace digital board

# print startup message
print "PiFace SNMP Monitor initialized and running..."

# start temp reader

# main loop
while True:
        # read status pins
        pinDieselRunning = pfio.digital_read(1)
        pinDieselFault = pfio.digital_read(2)
        pinMainsLost = pfio.digital_read(3)
        pinAirCondition1Fault = pfio.digital_read(4)
        pinAirCondition2Fault = pfio.digital_read(5)

        # process Diesel RUN status pin
        parmon(pinDieselRunning, lstDieselRunning, msgdieselengaged, msgdieseldisengaged)

        # process Diesel FAULT status pin
        parmon(pinDieselFault, lstDieselFault, msgdieselfault, msgdieselclear)

        # process Mains status pin
        parmon(pinMainsLost, lstMainsLost, msgmainsfault, msgmainsclear)

        # process Air Condition FAULT status pins
        parmon(pinAirCondition1Fault, lstAirCondition1Fault, msgac1fault, msgac1clear)
        parmon(pinAirCondition2Fault, lstAirCondition2Fault, msgac2fault, msgac2clear)

        # process temperature alerts
        parmon(staTempHigh, lstTempHigh, msgtempalert, msgtempclear)

        # remember pin stati
        lstDieselRunning = pinDieselRunning
        lstDieselFault = pinDieselFault
        lstMainsLost = pinMainsLost
        lstAirCondition1Fault = pinAirCondition1Fault
        lstAirCondition2Fault = pinAirCondition2Fault
        lstTempHigh = staTempHigh

        # delay 100ms
Because I had trouble getting around escape syntax in python, I used a bash script to handle SNMP trap sending with Net-SNMP's snmptrap command. This is all very rudimentary as of yet. I might use pysnmp later on to do this:

Code: Select all


/home/pi/piface/python/piface/net-snmp-5.7.2/apps/snmptrap -v 1 -c public <receiver host> '' '' 6 99 '55' s "$1" 2> /dev/null
Note: Replace <receiver host> with the IP of your trap receiver.

To read the temperature, I used a HIDTemper USB thermometer, with some perl code:

Code: Select all

use strict;
use Device::USB::PCSensor::HidTEMPer;

my $pcsensor = Device::USB::PCSensor::HidTEMPer->new();
my @devices = $pcsensor->list_devices();

foreach my $device (@devices) {
        print $device->internal()->celsius() if defined $device->internal();
More info about this can be found at: ... emperature.

Hope you'll find this useful. Have fun with the Pi!

Re: SNMP Monitoring Box

Posted: Thu Feb 21, 2013 10:56 am
by gridrun
UPDATE: The perl code takes too long to execute, occasionally crashes the Pi and returns false readings every now and then. :lol: Using temper-1.0 code from Relavak Labs ( ... ux-driver/) works MUCH better.

See ... 51#p293351 for more information.

Re: SNMP Monitoring Box

Posted: Fri Feb 22, 2013 8:24 am
by gridrun
Hmm that was too quick!

The Pi still crashes on the Temper1, even with the Relavak code - though much less frequently.

It always seems to hang in bcm2708_spi_interrupt. A few questions arise:

* Might there be a problem with the SPI implementation?
* As I'm using a separate thread to read the temp - is the SPI implementation thread safe?

Re: SNMP Monitoring Box

Posted: Sun Feb 24, 2013 6:33 pm
by gridrun

Re: SNMP Monitoring Box

Posted: Tue Mar 19, 2013 12:20 pm
by djr357
Can you post your snmpd.conf? Im having a little difficulty making it respond to snmp requests and i believe i have followed every direction i have found so far! :)

Re: SNMP Monitoring Box

Posted: Tue Mar 19, 2013 12:47 pm
by djr357
i think i got it. It responds to a locally run snmpwalk command but still nothing from a remote machine. I know i need to put the machines IP that is allowed to run the query but do not know where to put it

Re: SNMP Monitoring Box

Posted: Tue Mar 19, 2013 12:59 pm
by djr357
nevermind - i got it

had to add:
agentAddress udp:161


rocommunity public <IP of remote machine>

good to go

Re: SNMP Monitoring Box

Posted: Thu Mar 21, 2013 12:12 pm
by gridrun
djr357 wrote:Can you post your snmpd.conf?
I'm not currently using snmpd.conf. I resorted to PySNMP for sending SNMP traps. But good to hear that you got it working!