NOAA Weather Probe Example

It is now easier than ever to build command-line probes. This example retrieves temperature data from the US NOAA weather feed in a particular city.

How does this probe work?

  1. Right-click a device and choose Select Probe.
  2. Select the Weather Service-Temp probe from the Miscellaneous/Test category.
  3. Enter the city code for the closest weather station (for example, KLEB, Lebanon Municipal Airport). The Status window shows the name of the weather station, with a chartable value for the temperature reading.

Under the covers, Intermapper launches a Python program to contact the weather service, retrieve the meteorological conditions for the indicated city, and parses the XML response to retrieve the temperature. (There is a lot more information in the Weather Service feed; you can extend the program to display more information.) The following are some features of this probe:

  • The ${PYTHON} macro provides the path to the built-in python interpreter of Intermapper DataCenter no matter what platform you use. For example, the probe can now use the following:

    cmd = "${PYTHON} program.py"

    Intermapper substitutes the proper path to invoke Python, whether on Microsoft Windows, macOS, or Linux systems.

    NOTE:

    To use this macro, the Intermapper DataCenter (IMDC) must be installed. IMDC is installed automatically with Intermapper 5.2 on Microsoft Windows and OSX systems; Linux systems require a separate installation for IMDC. 

  • You can include the script directly in the probe file text.This makes it easier to write scripts and keep the probe file in sync. To do this, use the <tool:program-name> section in your probe file. The example below contains a program named noaa-weather.py. When Intermapper loads the probe, it parses out this section and saves it in a folder within the Tools directory of Intermapper Settings. Programs in the <tools> section can also save private files in that directory.
  • The example probe file uses a few Python libraries. For example, urllib2 makes it easy to make queries from web services. It includes a few straightforward calls to build a URL, issue it, and retrieve the results.
  • The probe uses the xml.dom.minidom library to parse XML data returned from the NOAA web service. For more information on this library, see Chapter 9 of Dive into Python.

NOAA Temperature Probe

To use this probe, copy the text below, paste it to a text editor, save it to a text file, and click File > Import> Probe... in Intermapper.

<!--
Weather Service Temperature - Retrieve the temperature from the NOAA weather XML
(com.dartware.tool.noaa.txt) Copyright© Fortra, LLC.
Please feel free to use this as a base for further development.
-->

<header>
     type = "cmd-line"
     package = "com.dartware"
     probe_name = "tool.noaa"
     human_name = "Weather Service-Temperature"
     version = "1.3"
     address_type = "IP"
     display_name = "Miscellaneous/Test/Weather Service-Temp"
 </header>

<description>
\GB\Retrieve the current temperature\p\

This probe retrieves the current temperature from the NOAA weather feed. To see the proper city code, visit:

\u4=http://www.weather.gov/xml/current_obs/\http://www.weather.gov/xml/current_obs/\p0\
</description>

<parameters>
     "Weather Station" = "KLEB"
</parameters>

<command-line>
      path=""
      cmd="${PYTHON} noaa_weather.py"
      arg="${Weather Station}"
</command-line>

<command-exit>
      -- These are the exit codes used by Nagios plugins
        down: ${EXIT_CODE}=4
        critical: ${EXIT_CODE}=3
        alarm: ${EXIT_CODE}=2
        warn: ${EXIT_CODE}=1
        okay: ${EXIT_CODE}=0
</command-exit>

<command-display>
\b5\ Temperature for $loc\p0\
  Temperature: $temp \3g\degrees F\p0\
</command-display>

<tool:noaa_weather.py>

# noaa_weather.py
# Scan the XML results from NOAA's XML feeds
# e.g., http://www.weather.gov/xml/current_obs/KLEB.xml # for relevant weather-related information.
# 25 Mar 2009 -reb
import os
import re
import sys
import getopt
import urllib.request, urllib.parse, urllib.error
from xml.dom import minidom

# httplib.HTTPConnection.debuglevel = 1 # force debugging....
# options are: station

try:
       opts, args = getopt.getopt(sys.argv[1:], "")
except getopt.GetoptError as err:
       searchString = "getopt error %d" % (err)

station = args[0]
userAgent = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_ 5; en-us) AppleWebKit/525.18 (KHTML, like Gecko) 
             Version/3.1.2 Safari/525.20.1"
noaaString = "http://www.weather.gov/xml/current_obs/%s.xml"
noaaString = noaaString % (urllib.parse.quote_plus(station))

# print noaaString;
retcode = 4;
try:
      request = urllib.request.Request(noaaString)
      opener = urllib.request.build_opener()
      request.add_header('User-Agent', userAgent)
      usock= opener.open(request)
#	print buf
except IOError as e:
      if hasattr(e, 'reason'):
                    resp = 'We failed to reach a server. '
                    reason = 'Reason: ' + 'Wrong host name?' # e.reason[1]
      elif hasattr(e, 'code'):
                    resp = 'The server couldn\'t fulfill the request. '
                    reason = 'Error code: '+ str(e.code)
      print("\{ $temp := '%s', $loc := 'Unknown' } %s" % (0, resp + reason))
      sys.exit(retcode) # make it look down

retcode = 0 # looks like it'll succeed
xmldoc = minidom.parse(usock)
tempList = xmldoc.getElementsByTagName('temp_f')
tempElem = tempList[0]
tempval = tempElem.firstChild.data
loclist = xmldoc.getElementsByTagName('location')
locval = loclist[0].firstChild.data
print("\{ $temp := '%s', $loc := '%s' }%s" % (tempval, locval, tempval + ' degrees at ' + locval))
sys.exit(retcode)
</tool:noaa_weather.py>

See also

${PYTHON} macro - for the full path the to the Python interpreter.

- to include a script directly into the probe file.

Python Documentation:
   urllib2 - http://docs.python.org/library/urllib2.html
   xml.dom.minidom - http://docs.python.org/library/xml.dom.minidom.html

Dive into Python: for information on XML processing in Python, see
http://diveintopython.org/xml_processing/.