RMSv1 MRTG Perl Script



#!/usr/bin/perl
##############################################################################################################
# Remote Monitoring System - (C)2001 - 2008 RemoteMonitoringSystems                                          #
# Perl Script version 1.2                                                                                    #
#                                                                                                            #
# Copy this text and save it to a file called rms.pl                                                         #
#                                                                                                            #
# Make sure this file is executable! (chmod 755 rms.pl)                                                      #
#                                                                                                            #
# Usage: rms.pl [host] [password] [mode] [myitem]                                                            #
#                                                                                                            #
# [host] IP Address or Hostname                                                                              #
# [password] Password is limited to 10 characters                                                            #
# [mode] "normal" or "mrtg" or "rmsgrapher" or "adc_mv"                                                      #
# [myitem] Only used if [mode] is set to "mrtg" or "rmsgrapher" or "adc_mv"                                  #
#     Valid value's for [myitem] are: "adc1" "adc2" "adc3" "adc4" "adc5" "adc6" "adc7" "adc8" "temp"         #
#     [myitem] is not needed if [mode] is set to "normal".                                                   #
#                                                                                                            #
#                                                                                                            #
# Sample MRTG Entrys:                                                                                        #
#                                                                                                            #
# Unix Example                                                                                               #
# -----------------------------------------------------------------------                                    #
# Target[bnddev]: `/pathto/rms.pl 10.10.10.10 public mrtg adc1`                                              #
# MaxBytes[bnddev]: 3000                                                                                     #
# Title[bnddev]: Battery Monitor ON SOME MOUNTAIN                                                            #
# PageTop[bnddev]: MOUNTAIN BATTERY MONITOR 24 Volt System                                                   #
# Unscaled[bnddev]: dwmy                                                                                     #
# Options[bnddev]: absolute, gauge, noinfo, nopercent                                                        #
# YLegend[bnddev]: Battery Voltage                                                                           #
# ShortLegend[bnddev]:                                                                                       #
# LegendI[bnddev]: Volts:                                                                                    #
# LegendO[bnddev]:                                                                                           #
# ------------------------------------------------------------------------                                   #
#                                                                                                            #
# Win32 Example                                                                                              #
# -----------------------------------------------------------------------                                    #
#Target[bnddev]: `perl c:\path-to\rms.pl 10.10.10.10 public mrtg adc1`                                       #
#MaxBytes[bnddev]: 3000                                                                                      #
#Title[bnddev]: Battery Monitor ON SOME MOUNTAIN                                                             #
#PageTop[bnddev]: MOUNTAIN BATTERY MONITOR 24 Volt System                                                    #
#Unscaled[bnddev]: dwmy                                                                                      #
#Options[bnddev]: absolute, gauge, noinfo, nopercent                                                         #
#YLegend[bnddev]: Battery Voltage                                                                            #
#ShortLegend[bnddev]:                                                                                        #
#LegendI[bnddev]: Volts:                                                                                     #
#LegendO[bnddev]:                                                                                            #
# ------------------------------------------------------------------------                                   #
#                                                                                                            #
# Note: MRTG does not like decimal points. If your voltmeter reads 12.34 volts, MRTG will graph 1234.        #
# MRTG with RRDTOOL instead of RATEUP could support decimal values, If this script was modified.             #
#                                                                                                            #
#                                                                                                            #
##############################################################################################################

#Includes
use IO::Socket;
use IO::Select;
use constant MAX_MSG_LEN  => 505;

#######################################
###User Variables PLEASE EDIT THESE!###
#######################################

#uncomment and edit these if you would like to run this script without command line arguments.
#$defaultip = "10.10.10.10";
#$defaultpasswd = "public";
#$defaultmode = "normal"; # This can be "normal" or "mrtg" or "rmsgrapher" or "adc_mv"
#$defaultmyitem = "adc1"; # This can be "adc1" "adc2" "adc3" "adc4" "adc5" "adc6" "adc7" "adc8" "temp"


###########################################################
###System Variables DO NOT EDIT ANYTHING BELOW THIS LINE###
###########################################################

chomp $mypasswd;
$rev = "Ver 1.1";
$host = shift || $defaultip;
$mypasswd = shift || $defaultpasswd;
$themode = shift || $defaultmode;
$myitem = shift || $defaultmyitem;
$bcommand = "&^BND20011$mypasswd*********************************************************************************************************************************************************************************************";

###########################################################################
## Main Program ###########################################################
###########################################################################


if ($host eq "") {print "\nPlease specify the ip address or hostname, password, and mode\n\n";exit;}
if ($mypasswd eq "") {print "\nPlease specify the password\n";exit;}
if ($themode eq "") {print "\nPlease specify the mode: 'normal' or 'mrtg' or 'rmsgrapher' or 'adc_mv'\n\n";exit;}

&fillvars;
##### Try up to 5 more times to get the info if no response.

if (length($msg_in) < 5) { &fillvars; }
if (length($msg_in) < 5) { &fillvars; }
if (length($msg_in) < 5) { &fillvars; }
if (length($msg_in) < 5) { &fillvars; }
if (length($msg_in) < 5) { &fillvars; }
if (length($msg_in) < 5) { die "Could not retrive info!!"; }

if ($themode eq "normal") {&showinfo;}
if ($themode eq "mrtg") {&domrtg;}
if ($themode eq "rmsgrapher") {&rmsgrapher;}
if ($themode eq "adc_mv") {&adc_mv;}

print "\nUsage: rms.pl [host] [password] [mode] [myitem]\n\n"; 
exit;

############################################################################
## Subroutines #############################################################
############################################################################

sub adc_mv {

if ($myitem eq "adc1") { print $adc1mv;exit;}
if ($myitem eq "adc2") { print $adc2mv;exit;}
if ($myitem eq "adc3") { print $adc3mv;exit;}
if ($myitem eq "adc4") { print $adc4mv;exit;}
if ($myitem eq "adc5") { print $adc5mv;exit;}
if ($myitem eq "adc6") { print $adc6mv;exit;}
if ($myitem eq "adc7") { print $adc7mv;exit;}
if ($myitem eq "adc8") { print $adc8mv;exit;}

}

sub rmsgrapher {

if ($myitem eq "adc1") { print "$adc1";exit;}
if ($myitem eq "adc2") { print "$adc2";exit;}
if ($myitem eq "adc3") { print "$adc3";exit;}
if ($myitem eq "adc4") { print "$adc4";exit;}
if ($myitem eq "adc5") { print "$adc5";exit;}
if ($myitem eq "adc6") { print "$adc6";exit;}
if ($myitem eq "adc7") { print "$adc7";exit;}
if ($myitem eq "adc8") { print "$adc8";exit;}
if ($myitem eq "temp") { print "$temp";exit;}

}

sub domrtg {
#$uptimeval = "Unknown :(";

$uptimeval = $secs / 60 /60 /24;
$uptimeval = sprintf("%.2f",$uptimeval) . " Days";
 
if ($myitem eq "adc1") { $adc1=$adc1*100; print "$adc1\n$adc1\n$uptimeval\n$myitem\n";exit;}
if ($myitem eq "adc2") { $adc2=$adc2*100; print "$adc2\n$adc2\n$uptimeval\n$myitem\n";exit;}
if ($myitem eq "adc3") { $adc3=$adc3*100; print "$adc3\n$adc3\n$uptimeval\n$myitem\n";exit;}
if ($myitem eq "adc4") { $adc4=$adc4*100; print "$adc4\n$adc4\n$uptimeval\n$myitem\n";exit;}
if ($myitem eq "adc5") { $adc5=$adc5*100; print "$adc5\n$adc5\n$uptimeval\n$myitem\n";exit;}
if ($myitem eq "adc6") { $adc6=$adc6*100; print "$adc6\n$adc6\n$uptimeval\n$myitem\n";exit;}
if ($myitem eq "adc7") { $adc7=$adc7*100; print "$adc7\n$adc7\n$uptimeval\n$myitem\n";exit;}
if ($myitem eq "adc8") { $adc8=$adc8*100; print "$adc8\n$adc8\n$uptimeval\n$myitem\n";exit;}
if ($myitem eq "temp") { $tempf=sprintf("%d",$tempf); print "$temp\n$tempf\n$uptimeval\n$myitem\n";exit;}

print "\n\nInvalid myitem specified\nValid value's are: adc1 adc2 adc3 adc4 adc5 adc6 adc7 adc8 temp\n";
exit;
}

######################################

sub showinfo {
print "\n************************************************************\n";
print "* RMSv1 Perl DataGrabber by RemoteMonitoringSystems.     $rev  *\n";
print "************************************************************\n\n";

print " Firmware Rev: $fwrev    Station Name: $station\n";
print " MAC Address: $mac   IP Address: $host\n\n";
print " ADC1 (0-30): $adc1\n";
print " ADC2 (0-30): $adc2\n";   
print " ADC3 (0-30): $adc3\n";
print " ADC4 (0-30): $adc4\n";
print " ADC5 (0-30): $adc5\n";
print " ADC6 (0-5) : $adc6\n";
print " ADC7 (0-5) : $adc7\n";
print " ADC8 (0-5) : $adc8\n";
print " TEMP: $temp C   $tempf F\n\n";

print " Relay1 -$rly1-  Relay2 -$rly2-  Relay3 -$rly3-\n\n";  
print " IO1 -$io1-  IO2 -$io2-  IO3 -$io3-  IO4 -$io4-  IO5 -$io5-\n\n";

$uptimeval1 = $secs / 60 /60 /24;
$uptimeval1 = sprintf("%.2f",$uptimeval1);

print " UPTIME: $secs Seconds $uptimeval1 Days\n\n\n";

exit;
}

######################################

sub fillvars {
$sock = IO::Socket::INET->new(Proto=>'udp',PeerAddr=>"$host:7",Timeout => "3")  or die $@;
$sel = IO::Select->new;
$sel->add($sock);
$sock->send($bcommand) or die "send() failed: $!";
sleep 1;
while ($sel->can_read(0)) { $sock->recv($msg_in,MAX_MSG_LEN) or die "recv() failed: $!"; }

$CorrectPassword = ord(substr($msg_in,10,1));
if ($CorrectPassword ne "0")
	{
	print "Bad Password\n";
	exit;	
	}	

#Get Firmware Version
$fwrev_H = ord(substr($msg_in,65,1));
$fwrev_L = ord(substr($msg_in,66,1));
$fwrev_M = ord(substr($msg_in,67,1));
$fwrev = "$fwrev_H.$fwrev_L$fwrev_M";

#Get Mac Address
$mac1 = uc(sprintf("%x",ord(substr($msg_in,14,1))));
$mac2 = uc(sprintf("%x",ord(substr($msg_in,15,1))));
$mac3 = uc(sprintf("%x",ord(substr($msg_in,16,1))));
$mac4 = uc(sprintf("%x",ord(substr($msg_in,17,1))));
$mac5 = uc(sprintf("%x",ord(substr($msg_in,18,1))));
$mac6 = uc(sprintf("%x",ord(substr($msg_in,19,1))));
$mac = "$mac1:$mac2:$mac3:$mac4:$mac5:$mac6";

#Get ADC Values
$adc1_hi = ord(substr($msg_in,20,1));
$adc1_lo = ord(substr($msg_in,21,1));
$hexval1_hi = sprintf ("%x", $adc1_hi);
$hexval1_lo = sprintf ("%x", $adc1_lo);
$adc = hex($hexval1_hi . $hexval1_lo) / 4095 * 30;
$adc1mv = $adc*1000;
$adc1mv = sprintf("%.0f",$adc1mv);
$adc1 = sprintf("%.2f",$adc);


$adc2_hi = ord(substr($msg_in,22,1));
$adc2_lo = ord(substr($msg_in,23,1));
$hexval2_hi = sprintf ("%x", $adc2_hi);
$hexval2_lo = sprintf ("%x", $adc2_lo);
$adc = hex($hexval2_hi . $hexval2_lo) / 4095 * 30;
$adc2mv = $adc*1000;
$adc2mv = sprintf("%.0f",$adc2mv);
$adc2 = sprintf("%.2f",$adc);

$adc3_hi = ord(substr($msg_in,24,1));
$adc3_lo = ord(substr($msg_in,25,1));
$hexval3_hi = sprintf ("%x", $adc3_hi);
$hexval3_lo = sprintf ("%x", $adc3_lo);
$adc = hex($hexval3_hi . $hexval3_lo) / 4095 * 30;
$adc3mv = $adc*1000;
$adc3mv = sprintf("%.0f",$adc3mv);
$adc3 = sprintf("%.2f",$adc);

$adc4_hi = ord(substr($msg_in,26,1));
$adc4_lo = ord(substr($msg_in,27,1));
$hexval4_hi = sprintf ("%x", $adc4_hi);
$hexval4_lo = sprintf ("%x", $adc4_lo);
$adc = hex($hexval4_hi . $hexval4_lo) / 4095 * 30;
$adc4mv = $adc*1000;
$adc4mv = sprintf("%.0f",$adc4mv);
$adc4 = sprintf("%.2f",$adc);

$adc5_hi = ord(substr($msg_in,28,1));
$adc5_lo = ord(substr($msg_in,29,1));
$hexval5_hi = sprintf ("%x", $adc5_hi);
$hexval5_lo = sprintf ("%x", $adc5_lo);
$adc = hex($hexval5_hi . $hexval5_lo) / 4095 * 30;
$adc5mv = $adc*1000;
$adc5mv = sprintf("%.0f",$adc5mv);
$adc5 = sprintf("%.2f",$adc);

$adc6_hi = ord(substr($msg_in,30,1));
$adc6_lo = ord(substr($msg_in,31,1));
$hexval6_hi = sprintf ("%x", $adc6_hi);
$hexval6_lo = sprintf ("%x", $adc6_lo);
$adc = hex($hexval6_hi . $hexval6_lo) / 4095 * 5;
$adc6mv = $adc*1000;
$adc6mv = sprintf("%.0f",$adc6mv);
$adc6 = sprintf("%.2f",$adc);

$adc7_hi = ord(substr($msg_in,32,1));
$adc7_lo = ord(substr($msg_in,33,1));
$hexval7_hi = sprintf ("%x", $adc7_hi);
$hexval7_lo = sprintf ("%x", $adc7_lo);
$adc = hex($hexval7_hi . $hexval7_lo) / 4095 * 5;
$adc7mv = $adc*1000;
$adc7mv = sprintf("%.0f",$adc7mv);
$adc7 = sprintf("%.2f",$adc);

$adc8_hi = ord(substr($msg_in,34,1));
$adc8_lo = ord(substr($msg_in,35,1));
$hexval8_hi = sprintf ("%x", $adc8_hi);
$hexval8_lo = sprintf ("%x", $adc8_lo);
$adc = hex($hexval8_hi . $hexval8_lo) / 4095 * 5;
$adc8mv = $adc*1000;
$adc8mv = sprintf("%.0f",$adc8mv);
$adc8 = sprintf("%.2f",$adc);

#Get Temp
$temp_hi = ord(substr($msg_in,68,1));              #temp byte
$temp_lo = ord(substr($msg_in,69,1));              #flag byte

if ( $fwrev => 167 )
# Firmware 1.67 and above is done like this...
	{
	if ($temp_lo == 0) 				# Not Neg, Not .5	
	        {
	        $temp =  ($temp_hi);
	        $tempf = (((9/5) * $temp) + 32);
	        }

	elsif ($temp_lo == 1)				# Neg, Not .5
	        {
	        $temp = "-" . ($temp_hi);
	        $tempf = (((9/5) * $temp) + 32);
	        }

	elsif ($temp_lo == 128)				# Not Neg, .5
		{
	        $temp = ($temp_hi + .5);
	        $tempf = (((9/5) * $temp) + 32);	
		}

	elsif ($temp_lo == 129)				# Neg, .5
		{
	        $temp = "-" . ($temp_hi + .5);
	        $tempf = (((9/5) * $temp) + 32);	
		}
	}
elsif ( $fwrev <= 166 )	# Firmware <= 1.66 is done like this...
# Firmware wasnt 1.67
	{
	if ($temp_lo == 0) 
        	{
        	$temp =  ($temp_hi / 2);
        	$tempf = (((9/5) * $temp) + 32);
        	}
	else
	        {
        	$temp = "-" . ($temp_hi / 2);
        	$tempf = (((9/5) * $temp) + 32);
        	}
	}
	
#Get Uptime
$sec1 = ord(substr($msg_in,73,1));              #uptime byte1 (Seconds)
$sec2 = ord(substr($msg_in,74,1));              #uptime byte2 (Seconds)
$sec3 = ord(substr($msg_in,75,1));              #uptime byte3 (Seconds)
$sec4 = ord(substr($msg_in,76,1));              #uptime byte4 (Seconds)

$sec1h = sprintf ("%x", $sec1);
if (length($sec1h) == 1) {$sec1h = "0" . $sec1h;}
$sec2h = sprintf ("%x", $sec2);
if (length($sec2h) == 1) {$sec2h = "0" . $sec2h;}
$sec3h = sprintf ("%x", $sec3);
if (length($sec3h) == 1) {$sec3h = "0" . $sec3h;}
$sec4h = sprintf ("%x", $sec4);
if (length($sec4h) == 1) {$sec4h = "0" . $sec4h;}

$secs = hex($sec4h . $sec3h . $sec2h . $sec1h);
$secs = "Unsupported In This RMS Firmware" if $secs == 707406378;

#Get Relay Status
$rly1 = ord(substr($msg_in,36,1));
if ($rly1 == 0) { $rly1 = "On"; } else { $rly1 = "Off"; }
$rly2 = ord(substr($msg_in,37,1));
if ($rly2 == 0) { $rly2 = "On"; } else { $rly2 = "Off"; }
$rly3 = ord(substr($msg_in,38,1));
if ($rly3 == 0) { $rly3 = "On"; } else { $rly3 = "Off"; }

#Get IO Pin Status
$io1 = ord(substr($msg_in,61,1));
$io2 = ord(substr($msg_in,62,1));
$io3 = ord(substr($msg_in,63,1));
$io4 = ord(substr($msg_in,64,1));
$io5 = ord(substr($msg_in,39,1));

#Get Station Name
$station = "";
for ($bb = 77; $bb <= 96; $bb++)
	{
	$mybuf = chr(ord(substr($msg_in,$bb,1)));
	$station = $station . $mybuf;
	}

$sock->close;
}