- System Monitoring
- Network Security
- Email Servers
- Email Scanning
- Operating Systems
- File & Print Servers
- SAN Solutions
- Budget Planning
- DNS Servers
- Web Servers
- Server Virtualization
- e-Learning
- Backup Solutions
- Database Servers
- Helpdesk Software
- Instant Messaging
- Network Fax Servers
- Website (CMS)
- Web Filtering
- Terminal Servers (LTSP)
- Wireless Systems
- Firewall & VPN
Remote Support & Installation
For nearly ten years now, Reverse Polarity has been remotely installing and configuring all of the software products we support. This includes writing or integrating custom scripts like the one below into your environment.
If you are interested in having us perform a remote installation of Xymon, Bacula, Cerberus or any other product. Or if you need help with installing and integrating a custom script like the one below, we would be happy to assist!
Please contact us for our rates and our requirements for secure remote access at 860-824-2433.
Thank you!
Xymon & ControlByWeb Temperature Monitor Script
Purpose
The instructions and script that follow are intended to be used to monitor 1 to 4 temperature readings from a ControlByWeb's 4-temp/2-relay temperature monitor module OR 1 to 8 temperature readings from the X-300 8-temp/3-relay 7-day programmable thermostat module and report temperature readings back to a Xymon monitoring server for logging, graphing and alerting.
Here you will find the most current versions of our:
- Instructions on integrating, monitoring, graphing and alerting on the output from the xymon_cbw_temp.sh script with a Xymon server
- xymon_cbw_temp.sh - Xymon/ControlByWeb temperature module & X-300 thermostat module monitoring script
Related Scripts
We have also written several other scripts that you may find useful. You may find them HERE
Instructions
ControlByWeb Temperature Module Configuration
First you need to do some basic configuration of the ControlByWeb temperature module. Instructions are included with the device, but the basic steps are as follows:
- Connect: Connect to the device's default IP address using a web browser: http://192.168.1.2/setup.html (USER is blank, default password is webrelay)
- Network Tab: Set up its network settings to match your network environment.
- Email Tab: Optional since we will be alerting using Xymon.
- Password Tab: Recommended, but also optional.
- Main Tab: Set the temperature scale (Celsius or Fahrenheit). The rest of the options on this tab are optional for our configuration.
- Sensor1 - Sensor4 Tabs: The only setting required for our configuration is the "Sensor Address". Choose the appropriate "Sensor Address" from the drop down list. Set the "Sensor Description" to aid in troubleshooting later if you like. The rest of the settings are optional, but can be useful, especially in the case of operating one of the local relays when a temperature threshold is crossed.
- Reboot: Reboot the ControlByWeb module to complete the network configuration, and then try connecting to it at its new IP address.
Xymon Configuration
Install the custom external script
- Copy the bash shell script below into ~xymon/server/ext/xymon_cbw_temp.sh
- Set the ownership and execution permissions on the script
chown xymon:xymon ~xymon/server/ext/xymon_cbw_temp.sh chmod +x ~xymon/server/ext/xymon_cbw_temp.sh
Edit script to match your environment
- The script is pretty well documented, but you do need to modify just a couple of the pre-configured variables to get started:
- Local system binaries: (GREP, TR & CURL)
- HOST - The IP address or FQDN of the ControlByWeb device (host.example.com in our case)
- USER - Leave blank for a ControlByWeb temperature module
- PASS - Set to "webrelay", or set to same password used when you configured ControlByWeb device
- ZONES - These are documented in the script and should be pretty easy to understand there
Tell Xymon (hobbitlaunch) to start running the new script
- Tell Xymon to start running the new external script by adding these lines to ~xymon/server/etc/hobbitlaunch.cfg:
[cbwtemp]
ENVFILE /usr/local/xymon/server/etc/hobbitserver.cfg
CMD $BBHOME/ext/xymon_cbw_temp.sh
INTERVAL 5m
- Wait a few minutes and you should see a new column called cbwtemp on your Xymon page
- Click on the cbwtemp icon and you should see the new cbwtemp test reading(s) with a timestamp of the latest update similar to the image below:

Let's get to the graphing!
- It is a two step process to get Xymon to begin graphing our data.
- First we need to tell Xymon to start putting our temperature readings into RRD (Round Robin Database) files
- Next we need to tell Xymon how we want our graph to look, and what info we would like printed on it
- Edit ~xymon/server/etc/hobbitserver.cfg.
- Find the TEST2RRD line and add our new test to the end like so:
TEST2RRD="cpu=la,disk,inode....hobbitd,clock,lines,cbwtemp=ncv"
That tells Xymon to map our new column called cbwtemp to rrd file(s), and that Xymon should send the data through the built-in NCV (name-colon-value) module.
- Tell Xymon to also include our new cbwtemp graph on the trends page by adding it to the GRAPHS definition line in the hobbitserver.cfg file like so:
GRAPHS="la,disk,inode,qtree...hobbitd,clock,lines,cbwtemp"
- Add this line to the end of your hobbitserver.cfg file.
SPLITNCV_cbwtemp="*:GAUGE"
That tells Xymon to create a series of RRD files, one for each NCV pair reported by the xymon_cbw_temp.sh script for the cbwtemp column. The datasets will be of type GAUGE (since temperatures go up and down and are not always-increasing counter type readings). The files Xymon creates will be called ~xymon/data/rrd/host.example.com/cbwtemp,Location.rrd where each Location will be one of the locations you set up in the ZONES variable in the xymon_cbw_temp.sh script.
Xymon needs to be restarted at this point to pick up the new configurations changes/additions. Alternately, you may just kill any running hobbitd_rrd and hobbitd_channel processes and Xymon will restart them using the new settings from hobbitserver.cfg.
- At this point we should verify that our new rrd files exist:
$ ls -1 ~xymon/data/rrd/host.example.com/cbwtemp* /usr/local/xymon/data/rrd/host.example.com/cbwtemp,Office.rrd /usr/local/xymon/data/rrd/host.example.com/cbwtemp,Outside.rrd /usr/local/xymon/data/rrd/host.example.com/cbwtemp,ServerRoom.rrd
And then we can also verify that our expected data is in these files.
We should verify three values: the name <name>, type of test <type>, and last value received <last_ds>:
$ rrdtool dump ~xymon/data/rrd/host.example.com/cbwtemp,ServerRoom.rrd | grep "name\|type\|last_ds"
<name> lambda </name>
<type> GAUGE </type>
<last_ds> 78.1 </last_ds>
Wait! What? lambda?? Shouldn't that say ServerRoom?? No, this is correct. When using SPLITNCV the dataset names in each of the rrd files will be lambda. Notice though, that the type is GAUGE, and that the last_ds value of 78.1 degrees Fahrenheit looks like a reasonable temperature reading for our server room (ok, not really... but we're just demonstrating here). So far, So good. You may check the other cbwtemp,*.rrd files if you like to confirm they are OK too.
Now if you view the cbwtemp status page, you will notice that there is still no graph being drawn. That is OK, because we haven't configured Xymon's hobbitgraph.cfg file to define how Xymon is supposed to graph our new column yet.
**note to waa** Remember to explain how to use "rrdtool tune" to set the MIN to a negative number if you are expecting negatives. Alternately, maybe there is some more proper documentation for the SPLITNCV_testname=.... line in the hobbitserver.cfg file so that may be configured automatically at time of the rrd file's creation.
Revision - 20100-07-10: No need, since this was just addressed as a bug fix yesterday. See: Revision: 6324
- Edit ~xymon/server/etc/hobbitgraph.cfg and add the following lines: (see explanation below)
[cbwtemp]
FNPATTERN cbwtemp.(.+).rrd
TITLE Temperature
YAXIS Fahrenheit
DEF:p@RRDIDX@=@RRDFN@:lambda:AVERAGE
LINE1.5:p@RRDIDX@#@COLOR@:@RRDPARAM@
GPRINT:p@RRDIDX@:LAST: \: %5.1lf (cur)
GPRINT:p@RRDIDX@:MAX: \: %5.1lf (max)
GPRINT:p@RRDIDX@:MIN: \: %5.1lf (min)
GPRINT:p@RRDIDX@:AVERAGE: \: %5.1lf (avg)\n
- The hobbitgraph.cfg entry explained:
[cbwtemp] : Defines the name of the graph and must match the name
of the status column to have this graph appear on the
cbwtemp status page
FNPATTERN : Describes what rrd files(s) should be read to generate the
graph for this column. In our case we are telling it to
look for cbwtemp(anything).rrd files.
TITLE/YAXIS : These define the graph's title and y-axis legend
DEF :
LINE1.5 : This says draw a line of thickness "1.5"
GPRINT : The next sets of four lines print out the Last, Maximum,
Minimum and Average vales in the rrd file for our tests
- We're done!
- Now, reload the cbwtemp page and you should start seeing something similar to the image below:

- Special thanks to goldfndr in the #xymon IRC channel on freenode for motivating and helping me to convert these instructions to use SPLITNCV instead of NCV.
xymon_cbw_temp.sh
#!/bin/bash # # NAME # ---- # - xymon_cbw_temp.sh # # DESCRIPTION # ----------- # - Simple Bash shell script to monitor from 1 to 4 temperature readings # from a ControlByWeb 4-temp/2-relay module and the X-300 8-temp/3-relay # 7-day programmable thermostat module and report status and # temperature readings back to a Xymon server # # - The most current version of this script may be # found at http://www.revpol.com/xymon_cbw_temp_script # # - Instructions to integrate the output of this script to be monitored # and graphed by a Xymon server may also be found at the above URL # # - If you find this script useful, I'd love to know. Send me an email or # leave a comment at the bottom the script page! # # William A. Arlofski # Reverse Polarity, LLC # 860-824-2433 Office # http://www.revpol.com/ # # HISTORY # ------ # - 20100307 - Initial version release # - 20100318 - Minor modifications to also work with the new # X-300 (8-temp & thermostat) module # - Increased the curl timeout from 3 to 10 seconds # - 20100319 - Modifications to deal with a situation where a temperature # sensor stops communicating with the module. Modified 2nd # grep in getcurtemp() module and added testcomm() function to # see if the current temp is "xx.x" and flag CURCOLOR and COLOR # as red if yes # - 20100322 - Added "ADMINMSG" variable to allow for an administrative # messages to be added to the top of the report # - 20100408 - Minor errors in grammar fixed # - 20100520 - Modification to getcurtemp() function to catch cases where the # whole number portion of the temperature was a single digit. # ############################################################################### # # Copyright (C) 2010 William A. Arlofski - waa-at-revpol-dot-com # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # or visit http://www.gnu.org/licenses/gpl.txt # ############################################################################### # # Set some variables # ------------------ # Local System Binaries # --------------------- GREP="/bin/grep" TR="/usr/bin/tr" CURL="/usr/bin/curl" # Location/device specific variables # ---------------------------------- # # FQDN or IP address of the ControlByWeb # temperature monitor to pull data from # and user login and password # (User should be blank) #--------------------------------------- HOST="host.example.com" USER="" PASS="" # Define the temperature zone(s) to monitor # ----------------------------------------- # Format is as follows: # # ZONE="Sensor#:TestType:Location:WarnTmp1:CritTmp1:[WarnTmp2:CritTmp2] \ # [ Sensor#:TestType:Location:WarnTmp:CritTmp:[WarnTmp2:CritTmp2] ...]" # # Where the fields are as follows: # - Sensor : The sensor number from 1 to 4 # - TestType : The type of test: UP, DOWN, RANGE, IGNORE. # If TestType is RANGE, WarnTmp2 and CritTmp2 are required # If TestType is IGNORE, then only Sensor:TestType:Location are required # - Location : The name of the location - Must match your Xymon definitions # - WarnTmp1 : The value at which to set test COLOR and alert to yellow for UP or DOWN tests # For RANGE test types, this value is used as if the test were a DOWN test # - CritTmp1 : The value at which to set test COLOR and alert to red for UP or DOWN tests # For RANGE test types, this value is used as if the test were a DOWN test # - WarnTmp2 : Only used for RANGE type tests. The value at which to set test COLOR # to yellow as temperature increases # - CritTmp2 : Only used for RANGE type tests. The value at which to set test COLOR # to red as temperature increases # # # The ControlByWeb temperature monitor # supports up to four temperature sensors # and reports the temperature as XX.Y in # either Celsius or Fahrenheit # --------------------------------------- ZONES="1:UP:ServerRoom:78.0:80.0 \ 2:IGNORE:Outside \ 3:RANGE:Office:70.0:65.0:80.0:82.0 \ 4:DOWN:Basement:36.0:32.0" # Add an administrative message to the top of the report page # Not necessary, but can be a quick way to know what server # is polling a ControlByWeb module, where the module is # physically located, and perhaps some instructional # information # ----------------------------------------------------------- ADMINMSG="- server.example.com is the host polling host.example.com. - The host.example.com module physically resides in the main server room." ############################################################################### # -------------------------------------------------- # Nothing should need to be modified below this line # -------------------------------------------------- ############################################################################### # # ---------------------------- # Set required Xymon variables # ---------------------------- COLUMN="cbwtemp" COLOR="green" MSG="" # ---------------- # Set up functions # ---------------- # # Get the four sensor temperature outputs from the # "state.xml" page from ControlByWeb temperature monitor # ------------------------------------------------------ getdata() { TEMPS=`"$CURL" -s -m 10 -u "$USER:$PASS" "$HOST/state.xml"` # If the device returns no data, or is offline, or does not respond, # or if curl fails for any reason, then just fail and exit the script. # Xymon will alert purple indicating that it has not seen data for this # test after 20 minutes (default). I suppose we COULD instead force a # yellow alert for all temps for this device during this condition... # --------------------------------------------------------------------- EXIT="$?" if [ "$EXIT" != "0" ] || [ -z "$TEMPS" ] ; then exit 1 fi } # Separate zone components: # - Skip all temperature values for IGNORE test types # - Assign WarnTmp2 and CrtTmp2 for RANGE test types # --------------------------------------------------- parsezone () { sensornum=`echo "$zone" | cut -d':' -f1` testtype=`echo "$zone" | cut -d':' -f2 | "$TR" [a-z] [A-Z]` location=`echo "$zone" | cut -d':' -f3` if [ ! "$testtype" == "IGNORE" ] ; then warntemp1=`echo "$zone" | cut -d':' -f4` crittemp1=`echo "$zone" | cut -d':' -f5` if [ "$testtype" == "RANGE" ] ; then warntemp2=`echo "$zone" | cut -d':' -f6` crittemp2=`echo "$zone" | cut -d':' -f7` fi fi } # Pull current zone's temperature reading out of xml tags # ------------------------------------------------------- getcurtemp () { # Each of the four temperatures is represented # as a line[-][Y][Y]Y.Z # where X is the sensor number from 1 to 8, # Y is the temp in degrees, and Z is the tenths # We only want the numeric portion including the # negative (hyphen) symbol between the tags for # the current sensor we are looping for # Also need to check for "xx.x" in case a temperature # sensor is not communicating with the module # --------------------------------------------------- curtemp=`echo "$TEMPS" \ | "$GREP" -Eo "sensor$sensornum.*sensor$sensornum" \ | "$GREP" -Eo [-]*\(\(x\)\|\([0-9]\)\)\{1,3\}\.\(\(x\)\|[0-9]\)` } # Test to make sure that we have a numeric value and not "xx.x" # which would mean that this temperature sensor is broken, or # otherwise not communicating with the module. Flag this test's # CURCOLOR red and the main test COLOR red as well. # ------------------------------------------------------------- testcomm () { if [ "$curtemp" == "xx.x" ] ; then CURCOLOR="red" # Now, since red is the most critical color, just set # the main status color for this report to red too # --------------------------------------------------- COLOR="red" return 1 else return 0 fi } # Test for temperature RISING and set the test's CURCOLOR # Set the main COLOR variable for the Xymon report if necessary # ------------------------------------------------------------- testup() { # Is current temp greater than the critical temp? # ----------------------------------------------- if [ `echo "$curtemp" | "$TR" -d .` -ge `echo "$crittemp1" | "$TR" -d .` ] ; then CURCOLOR="red" # Now, since red is the most critical color, just set # the main status color for this report to red too # --------------------------------------------------- COLOR="red" # Is current temp greater than the warning temp? # ---------------------------------------------- elif [ `echo "$curtemp" | "$TR" -d .` -ge `echo "$warntemp1" | "$TR" -d .` ] ; then CURCOLOR="yellow" # Set main status color to yellow only if it is not already worse (red) # --------------------------------------------------------------------- if [ "$COLOR" != "red" ] ; then COLOR="yellow" fi fi } # Test for temperature DECREASING and set the test's CURCOLOR # Set the main COLOR variable for the Xymon report if necessary # ------------------------------------------------------------- testdown() { # Is current temp less than the critical temp? # -------------------------------------------- if [ `echo "$curtemp" | "$TR" -d .` -le `echo "$crittemp1" | "$TR" -d .` ] ; then CURCOLOR="red" # Now, since red is the most critical color, just set # the main status color for this report to red too # --------------------------------------------------- COLOR="red" # Is current temp less than the warning temp? # ------------------------------------------- elif [ `echo "$curtemp" | "$TR" -d .` -le `echo "$warntemp1" | "$TR" -d .` ] ; then CURCOLOR="yellow" # Set main status color to yellow only if it is not already worse (red) # --------------------------------------------------------------------- if [ "$COLOR" != "red" ] ; then COLOR="yellow" fi fi } # Test for temperature being within the defined RANGE # and set the test's CURCOLOR # Set the main COLOR variable for the Xymon report if necessary # ------------------------------------------------------------- testrange() { # Is the current temp outside of the high and low critical levels? # ---------------------------------------------------------------- if [ `echo "$curtemp" | "$TR" -d .` -le `echo "$crittemp1" | "$TR" -d .` ] \ || [ `echo "$curtemp" | "$TR" -d .` -ge `echo "$crittemp2" | "$TR" -d .` ] ; then CURCOLOR="red" # Now, since red is the most critical color, just set # the main status color for this report to red too # --------------------------------------------------- COLOR="red" # Is the current temp outside of the high and low warning levels? # --------------------------------------------------------------- elif [ `echo "$curtemp" | "$TR" -d .` -le `echo "$warntemp1" | "$TR" -d .` ] \ || [ `echo "$curtemp" | "$TR" -d .` -ge `echo "$warntemp2" | "$TR" -d .` ] ; then CURCOLOR="yellow" # Set main status color to yellow only if it is not already worse (red) # --------------------------------------------------------------------- if [ "$COLOR" != "red" ] ; then COLOR="yellow" fi fi } ########################################################### # ----------- # Main Script # ----------- # Use curl to pull the data from the module # ----------------------------------------- getdata # Loop through the defined zones # ------------------------------ for zone in $ZONES; do CURCOLOR="green" parsezone getcurtemp # Make sure that the sensor we are testing is # actually communicating before we move onto the # UP, DOWN, RANGE or IGNORE tests. # ---------------------------------------------- if testcomm ; then # Determine if this is an UP or DOWN test # --------------------------------------- case "$testtype" in UP ) testup ;; DOWN ) testdown ;; RANGE ) testrange ;; IGNORE ) # Do not test anything. Just append # the $CURCOLOR (green), $location # and $curtemp values to the Xymon # Server report for this "zone" ;; * ) exit 1 ;; esac fi # Build the text of the status message # that will be sent to the Xymon Server # ------------------------------------- MSG="${MSG} &$CURCOLOR $location : $curtemp" done # Prepend the administrative messaege to the report # ------------------------------------------------- MSG="${ADMINMSG} ${MSG}" # Send final report to Xymon Server # --------------------------------- $BB $BBDISP "status $MACHINE.$COLUMN $COLOR `date` ${MSG} " ###########################################################


Post new comment