by Brian Hindman

An instrumentation network for weather data on the Web

how-to
May 1, 199930 mins

Use Java to display data from realtime devices to Web browser clients

This is the first installment in a series of Java Developer columns devoted to the concept of instrumentation over the Web. This month we’ll build a low-cost weather station and interface it to the Web. First, we’ll introduce the concepts of building Web-based data collection, monitoring, and control systems. Next, we’ll present an application, the 1-wire weather station, that uses Java servlet technology to post weather data to a Web server. This will be followed by a discussion of how to use Java to build systems with similar and/or different requirements. We’ll point you to established and recognized sources of expertise on the Web that are already running weather data but that don’t use Java. You can judge for yourself whether using Java technology could improve the current status quo.

In this article we’ll also lay the groundwork for new combinations of Java technology — for example, XML and object stores — so that low-cost, easy-to-maintain systems for storing large amounts of time-varying data can be understood and prototyped. We’ll cover this theme in greater detail in future articles in this series, introducing Jini implementations and embedded-server versions, as well as introducing an authenticated interface to home-automation devices, which you will actually be able to build yourself. So, if you forget to turn the air conditioner on or want to change the thermostat, with just a few bucks and the information in these upcoming articles, you’ll be able to do these things securely with Java technology.

Enabling devices for the Web really does create new services. We aren’t talking about making your printer Internet-aware or using your PalmPilot to browse the Web; we’re talking about smaller things, like pool temperatures, door locks, weather data — actually, more data than we can list here — that could be used by factories and business offices with geographically dispersed locations. The most common example of this is a WebCam. If you’ve never seen a WebCam, we’ve included a URL for one in the Resources section. Cameras are easy to interface because well-defined interfaces already exist for them. What if you were asked to make the services or data from some other device available on the Web? Common wisdom in the past has been to connect instrumentation to private networks. This article explores this huge new growth area for Web-based interfaces using Java and Jini. How would you do it? That’s the question we’ll start to answer in this series. To bring this home, we’ll provide code examples that can be used with a real device. This article demonstrates how to interface Dallas Semiconductor’s low-cost weather station to the Internet so that data from this weather station is available around the clock to interested Web users.

The article is divided into five parts:

  • An introduction to the weather station

  • Building the weather station

  • Posting realtime weather observations to a weather servlet (a Dallas Semiconductor example of an application using servlets)

  • A code example for a simple Swing application using the Dallas Semiconductor weather station API

  • Going forward

Before we launch into a discussion of these four issues, it’s important to provide an explanation of realtime data collection and how Java enables this — a central concept behind the weather station application presented in this article.

Java and realtime data collection

What we mean by realtime is that the readings are from a peripheral unit that is directly connected to a computer — not collected from some database that was loaded even as recently as a few hours ago in preparation for vector operations on a supercomputer. Although this article focuses on the weather station from Dallas Semiconductor, the goal is to encourage discussion and design of solutions in line with the Java spirit of being open; in other words, diverse types of implementations (meaning different weather stations or other architectures) could be integrated that depart from this particular implementation.

In the future, several different types of weather stations could be offered by different manufacturers. These could use Ethernet and/or wireless protocols on the link layer as the communication media, with diverse protocols and APIs. The beauty of Java technology is that it has so many APIs that use a consistent methodology, enabling mere mortals to connect up different legacy applications with new applications and actually understand what they’re doing! For example, you can connect a Jini application with an RMI-based application and, yes, some of that horrible CGI code that you don’t want to change. The net result of having this power is to present an interface to users that hides all this complexity, yet leverages components that work. Java really facilitates migration to new technologies very well. We’ll demonstrate this in later articles about embedded Web servers.

In the early 1970s, coauthor Rinaldo Di Giorgio worked for the Environmental Protection Agency (EPA), and the organization had as a national goal the instrumentation of the entire water system of the United States. If Java had been available then, applying the concepts in this article would have resulted in a system that would be useful to many countries interested in getting a handle on pollution and global warming. The architectures and techniques we’re proposing here are ideally suited to massive deployments of data-collection systems, and Jini goes a long way toward making this type of deployment a reality.

Why does XML matter in realtime data collection?

Recently, there has been much discussion of XML. XML is an emerging standard that may solve the problem of data and formatting being bundled together as it is on an HTML page. JavaWorld featured a comprehensive article on XML, “XML for the absolute beginner,” in its April issue. XML provides a mark-up language that allows weather data to be tagged independently of the source data. In this article on the weather station, whenever you see data that is in a format that seems proprietary, assume it will eventually be tagged with XML as the standard matures and its adoption increases. Collecting realtime data requires an understanding of the data format, the ability to save the data as quickly as it arrives, and the ability to process this data. Data from realtime devices comes in many different formats. As a developer you will have to decode this data and store it. At the current time we’re not aware of devices that send XML data, but this would be useful in the marketplace — although embedding the necessary circuitry for this would probably increase costs significantly. If a device could send XML data directly, you wouldn’t need to develop proxies that take the input data stream, decode it, then process it, and then reformat it as XML when users request or want to use this data.

An introduction to the weather station

There are many weather sites on the Web. A partial list thereof is provided in the Resources section.

Recently, Dallas Semiconductor introduced its low-cost 1-wire weather station, which provides realtime readings of the following data:

  • Temperature
  • Wind speed
  • Wind direction

Here’s what the weather station looks like:

One of the reasons we chose the 1-wire weather station jointly produced by Dallas Semiconductor and Texas Weather Instruments is its low-cost architecture that uses a one-wire bus with inexpensive support components. The weather station can communicate both data and power over a single wire cable. The station has various sensors that require power and the ability to transmit data. These sensors are the DS2401 directional indicators for the compass, the DS2429 for wind speed, and the DS1820 for temperature. For those of you interested in a very technical description of the circuitry, the 1-wire weather station article published in Sensors magazine (see Resources) provides an excellent description. Information on the core technical components, the technical data sheets for the DS2401, DS1820, DS2429, and the one-wire protocol can also be found there.

Building the weather station

To obtain a 1-wire weather station, see Resources. Here you’ll also find directions on building the weather station. Once you have the kit in hand, building the weather station requires a modest amount of manual skill and a few tools. The following includes a list of the tools needed to build a weather station, a segment on mistakes to avoid while building it (based on personal experience!), and a note about testing the weather station.

Construction tools

Here’s a list of the tools you’ll need to build the weather station from the components contained in the kit:

  • A Phillips screwdriver
  • Adjustable pliers
  • Good silicon caulk (clear or white)
  • A compass
  • Additional cable — enough of the twisted-pair type to place the device where you need it

Common construction mistakes and how to avoid them

The weather station kit contains two long rods with rectangular PCB boards on the end. One PCB board contains one magnet; the other contains two magnets. The PCB board with one magnet should be connected to the wind vane, which requires only one magnet. When the vane turns, the magnet passes between eight one-wire chips. These relate to the 8 points of the compass (north, northeast, east, southeast, south, southwest, west, and northwest). To resolve 16 points of the compass, as the magnet passes between two chips, both chips show up on the one-wire bus. Hence, we get NNE, ENE, ESE, SSE, SSW, WSW, WNW, and NNW. The PCB board with two magnets should be turned by the anemometer cups. Each time a magnet passes over the one-wire counting chip, it counts a single pulse. Two magnets get better wind-speed resolution.

The weather station has a top and a bottom area inside the plastic casing shell. When assembling the unit, a common mistake is to swap the PCB board for wind direction with the PCB board for wind speed. When building the weather station make sure the wind vane is on the bottom and that the PCB board with 8 of the DS2401s is in the bottom half of the casing.

Test the weather station before mounting it

It’s easy to test the construction job you did. We recommend you do this before you go through the effort of installing the 1-wire weather station in a permanent location only to find out it doesn’t work. Do yourself a favor and test it! You can easily test it by running the program FindiButtonsConsole.class. You should see output like this:

D:WeatherexamplesFindiButtonsjava FindiButtonsConsole 
FindiButtonsConsole Java console application: Version 0.00 
Adapter/Port iButton Type and ID Description 
------------------------------------------------------------ 
DS9097U COM2 DS1920 5B000000261EB010 Digital thermometer measu... 
DS9097U COM2 DS1920 4000000008F19C10 Digital thermometer measu... 
DS9097U COM2 DS2407 9E0000000ABE1612 one-wire Dual Addressable S... 
DS9097U COM2 DS2407 F70000000AE86D12 one-wire Dual Addressable S... 
DS9097U COM2 DS1982 7700000105F11809 1024 bit Electrically Pro... 
DS9097U COM2 DS2423 CC00000000CA3C1D one-wire counter with 4096 ... 
DS9097U COM2 DS2423 1500000000A5011D one-wire counter with 4096 ... 

Mount the station in a safe place

Depending on where you mount the weather station, additional hardware may be required. Be very careful when mounting the station in high places: wind forces can disconnect parts and fling them at windows or, even worse, at a person. So, for those of you living in regions that have severe wind conditions, be sure to firmly bolt down the station with double-locking bolts.

Connecting the 1-wire weather station to your computer

The cable to the 1-wire weather station requires pins 2 and 3 on the RJ11 connector to be run directly to the DS9097. Inside the housing of the DS9097 are chips that convert RS232 from your computer to the Dallas one-wire Protocol. In earlier JavaWorld articles, we presented a tutorial on serial ports; see the Resources section for a link to this tutorial. The one-wire interface from Dallas Semiconductor was designed to overcome some of the limitations of RS232. Specifically, the one-wire interface works over greater distances, supports higher speeds, requires fewer wires, and can deliver power to the device at the other end of the cable as shown in Figure 2.

Testing and configuration

In the Resources section we’ve supplied a link to the complete source code. There you will find three example applications:

  • FindiButtons — A console application to find all iButtons on the one-wire bus.

  • WeatherConsole — A console application to find and read a 1-wire weather station.

  • WeatherSwing — A simple Java Swing application to find and read a 1-wire weather station. We’ll discuss a simple program that uses this data.

At this point you need to orient the directional iButtons and this is done as described in the code immediately below. The DS2041 weather vane has no compass in it so it can’t tell which direction is true north. It can only tell which way it is pointing relative to the other DS2041s. The WeatherConsole program allows you to do this easily. The procedure is very simple in that you need to point the vane around the compass points and assign a value to the compass point corresponding to the ID number for that particular DS2041. So the steps are:

  1. Run the program
  2. Record the data
  3. Rotate the vane
  4. Correlate ID3 with direction
  5. Record the correct mappings of ID number to compass direction
$ java -native WeatherConsole (Make sure you use native threads on Unix Systems) 
WeatherConsole Java console application: Version 0.00 
Arch: sparc, OS Name: SunOS, OS Version: 5.7 
Adapter enumeration: 
Adapter Name: DS9097U 
Adapter Port Description: serial communication port 
Adapter Class Version: 0.01 
Available ports: /dev/term/a /dev/term/b /dev/term/pc1 /dev/term/pc0 /dev/cua/a 
/dev/cua/b /dev/cua/pc1 /dev/cua/pc0 
Port enumeration: 
Port /dev/term/a selected 
Adapter not detected on port /dev/term/a 
Releasing /dev/term/a 
Port /dev/term/b selected 
Adapter DS9097U detected on port /dev/term/b 
Adapter ID: 7B00000157E41409 
Adapter Version: DS2480 based adapter, version 2 
No calibration files, ID direction reporting Not Calibrated yet 
weather station Devices: 
DS1820 4B00000025DB8710 
DS2407 070000000AC0E912 
DS2423 5900000000BB2E1D 
Press CTRL-C to stop reading weather station 
Output [Time, Temperature(F), Direction Serial Number(s), Wind speed(MPH)] 
00:58:16.60PM, 32.60, 45000003606DC201, 2.37 
00:58:19.34PM, 32.60, 45000003606DC201 47000003606DD101, 2.16 
00:58:21.66PM, 32.62, 45000003606DC201, 1.18 
00:58:23.95PM, 32.62, C0000003606DC501, 1.79 
00:58:26.26PM, 32.65, C0000003606DC501, 3.57

Once you get output similar to the above, you’ll need to calibrate the unit. Use the following procedure.

Step 1.

Weather stations that haven’t been configured will report the wind direction as one or two ID numbers. These ID numbers represent a unique direction on the 1-wire weather station. To convert these numbers into a true direction you must supply two text files. The first file provides a list of eight IDs that represent the eight DS2401s that are on the weather station in the correct order.

Step 2.

You can create this file mentioned above by slowly turning the vane and copying the ID numbers that are displayed into a txt file called “WeatherStationDirectionIDs.txt.”

Here is an example of that txt file:

1E00000273822601 
3700000273B16F01 
540000020057CC01 
AE0000020057D401 
720000020057D001 
FB00000273790101 
2000000273AB3401 
BD00000273823D01

In some cases, when the vane is between two devices the direction displayed will be two ID numbers. The 1-wire weather station can indicate 16 different directions for the wind vane. Following the format of the file supplied in the example source code, create a file that has the correct relationships between IDs and directions. A sample file is included in the source code.

Step 3.

Now, simply copy the IDs that are displayed when the weather vane points north.

These text files are read from the default directory, when the one-wire weather station starts up. Unless you move the station, you will not need to calibrate it again. Having reached this point in the article you are now able to run the supplied programs to query your 1-wire weather station for up-to-the-second weather information.

Posting realtime weather observations to a weather servlet

Once you have your weather station put together and the software operating properly, you may want to consider posting your weather observations to a Web site. Dallas Semiconductor has implemented a system for posting realtime weather observations to a Web server from multiple 1-wire weather stations and retrieving them upon request. The general idea behind the system is to have a Web page whereby anyone with access to a computer and the Internet can view current weather conditions from any reporting 1-wire weather station.

To accomplish this, Dallas Semiconductor designed a Java servlet on the Web-server side of things to “broker” and keep track of all of the incoming and outgoing weather observations. On the client side, a Java applet was designed to periodically contact the servlet and retrieve the most current weather observations available from the weather station selected by the user. To catch a glimpse of the above servlet in action, go to https://www.ibutton.com/weather and click on the appropriate links. There you’ll see live weather updates from Dallas Semiconductor’s facilities in Dallas, TX.

So, how does the servlet work? Once the reporting software has taken a weather observation from the remote station, it opens a URL to the servlet. The URL contains parameters for the time, temperature, wind speed, rainfall, and so on. The servlet then keeps track of the observation, along with observations from other reporting stations, in a Java vector. For example, let’s say the servlet resides on the fictitious Web server: www.ibuttonweather.com. Then, a sample weather post URL would be:

http://www.ibuttonweather.com:8080/servlet/weatherServlet?
Mode=0&WID=A20000000AC3EC12&Dat=2/23/99
&Tim=10:47:03PM&Tem=44.7&WSp=3&WDr=6
&RSp=0.13&Dar=2/19/99&Lon=-96.834016
&Lat=32.948076&Cod=English

Looking closely at the above URL can tell you everything about the weather post. The Web server’s name comes first, along with the port of the Web server on which the servlet is listening (8080). The next item on the URL line is: servlet/WeatherServlet. This tells the Web server software that a servlet — specifically, WeatherServlet.class — will be contacted. Everything after the question mark (?) is the actual weather post, which is made up of 10 parameters. The first is Mode, which can be 0, 1, or 2. A mode of 0 means that a weather post is taking place. A mode of 1 means that a request is being made by the applet for a weather observation. A mode of 2 means that the weather applet is requesting a list of reporting weather stations. After Mode comes the weather station address parameter: WID. Every one-wire chip from Dallas Semiconductor has a unique serial number embedded in it via laser. For this system, the station address is the unique serial number located in the one-wire chip of the serial-port adapter, which is the conduit through which the computer communicates to the weather station. This number is an important one. Because it is unique, the servlet can use it to identify individual weather stations and to search the Java vector for the specific weather observation being requested. The rest of the parameters in the above URL are pretty self-explanatory.

Following the station address on the above URL line is the date (Dat), time (Tim), temperature (Tem), wind speed (WSp), wind direction (WDr), rainfall amount (RSp), date of the last reset or zeroization of the raingauge (Dar), longitude (Lon), latitude (Lat), and the units of measure being used — “English” or “Metric” (Cod). Two of these parameters need a bit more discussion. Wind direction (WDr) is posted as a number between 0 and 15. This represents the 16 points of the compass that the weather station can resolve, with 0 being north (going clockwise), 4 east, 8 south, 12 west, and so on. For example, the above post gives “6” as the wind direction, which translates to “southeast.” The second parameter needing clarification is the units-of-measure parameter (Cod). For the units-of-measure parameter, if “English” is used, the rainfall is reported in inches, the temperature is reported in degrees Fahrenheit, and the wind speed is reported in miles-per-hour. Otherwise, they are reported in millimeters, degrees Celsius, and kilometers-per-hour.

As mentioned earlier, the servlet keeps a running list of weather stations in a Java vector. Each weather station is identifiable in the vector by its unique serial number. For each station, only the most current weather observation is retained. The next time a weather post occurs from a particular weather station, the previous weather observation is overwritten, and if a weather station has not posted a weather observation in 12 hours, the servlet purges the weather station from the vector.

Besides posting, the other two functions the servlet performs are serving up weather observations and listing the reporting weather stations. The weather viewer applet exclusively uses these two functions to communicate with the servlet. The following is a typical request for a weather observation made by the applet:

http://www.ibuttonweather.com/servlet/weatherServlet?Mode=1&UID=A20000000AC3EC12

From above, we know that Mode=1 means that the applet is requesting a weather observation. In this case, a request is being made for weather data from the remote station with the station address of A20000000AC3EC12. A typical response from the servlet would be:

"Dallas, TX";A20000000AC3EC12;2/23/99;10:47:03PM;44.7;3;SE;0.13;2/22/99;English

The applet then parses the above response from the servlet and displays it in a meaningful way.

The third function the servlet performs is listing the weather stations. The following is the URL for listing reporting weather stations:

http://www.ibuttonweather.com/servlet/weatherServlet?Mode=2

Again, from the above we know that Mode=2 tells the servlet to output a list of weather station IDs, with location strings associated with them. The typical response to the above post is:

A20000000AC3EC12("Dallas, TX");AE00000011747312("Oklahoma City, OK")

Notice that the weather station sites are separated by semicolons (;) and that locale information can be found within parentheses [()]. In this case, semicolons are delimiters for the applet. The applet uses Java’s handy StringTokenizer class to pick up each ID. As for the location strings (example, “Dallas, TX”), they are kept in a hashtable on the Web server where the servlet can access it. This table is purposely kept on the server side to help prevent posting of unwanted remarks to the Web site. Associated with each location string is the weather ID of the station. Plans are in the works to enhance the servlet’s capabilities. The single most powerful enhancement is to add a database to the system. Each weather observation posted to the servlet could be added to the database. The servlet will use standard SQL statements and communicate with the database through a JDBC connection. With a running history, a servlet could not only report current weather conditions, but output seasonal high and low temperatures, wind speeds, and so on. The applet requesting the data could then display the information in a meaningful way through graphs, reports, and so on.

Example: A simple Swing application using the weather station API

The class WeatherStation contains an API that can be used to build Java applets, applications, and servlets. This interface is documented, and a link to it is provided in the Resources section.

The following code segments demonstrate the implementation of a Listener class that gets weather data and displays it in a Swing application. The code, ReadWeatherStationListener.java, is included in the Weather Kit from Dallas Semiconductor. Even though the example is specific to a weather station, it should be regarded as a basic essential Java design pattern.

class ReadWeatherStationListener <b>implements</b> ActionListener <b>{
</b>   <i>//-------------------------------------------------------------
</i>   <i>//-------- Variables
</i>   <i>

//-------------------------------------------------------------

</i> <i>//------------------------------------------------------------- </i> <i>/** Reference to the weatherPanel to enable reporting back results of * weather station read. */ </i> <b>private</b> WeatherSwing weatherPanel<b>

;

</b> <i>//------------------------------------------------------------- </i> <i>/** Object to read the 1-wire weather station. */ </i> <b>private</b> WeatherStation weatherStation<b>

;

</b> <i>//------------------------------------------------------------- </i> <i>/** String to contain the last error */ </i> <b>private</b> String lastError<b>

;

</b> <i>//------------------------------------------------------------- </i> <i>//-------- Constructors </i> <i>

//-------------------------------------------------------------

</i> <i>//------------------------------------------------------------- </i> <i>/** Constructs a new action listener. Requires the weather station * panel object that contains the 'updateWeather' method to pass * back results. * * @parameter newPanelReference weather station panel reference to * send back results to. */ </i> ReadWeatherStationListener<b>(</b>WeatherSwing newPanelReference<b>)</b> <b>{ </b> <i>// call the constructor of the super-class </i> <b>

super();

</b> <i>// collect the reference to the weather station panel </i> weatherPanel = newPanelReference<b>

;

</b> <i>// construct the string for error messages </i> lastError = <b>new</b> String<b>

();

</b> <i>// attempt to find the first valid iButton adapter by enumeration </i> <i>// (this could be replaced by user selection) </i> DSPortAdapter adapter = findFirstValidAdapter<b>

();

</b> <i>// if a valid iButton adapter was found then try to find weather station </i> <b>if</b> <b>(</b>adapter != <b>null)</b> <b>{ </b> <i>// construct the weather station object on this adapter </i> weatherStation = <b>new</b> WeatherStation<b>(</b>adapter<b>

);

</b> <i>// find weather station devices on adapter </i> <b>if</b> <b>(</b>weatherStation<b>.</b>findDevices<b>())</b> <b>{ </b> <i>// attempt to calibrate this weather station </i> weatherStation<b>.</b>setDirectionIDs<b>(</b> readIDFile<b>( </b> "WeatherStationDirectionIDs.txt"<b>).</b>elements<b>()); </b> weatherStation<b>.</b>setNorthReference<b>(</b> readIDFile<b>( </b> "WeatherStationDirectionReferenceID.txt"<b>). </b> elements<b>()); </b> <b>}</b> <b>else</b> <b>{ </b> lastError = weatherStation<b>.</b>getLastErrorAsString<b>(); </b> weatherStation = <b>null; </b> <b>} </b> <b>}</b> <b>else</b> <b>{ </b> lastError = "No valid one-wire adapter found"<b>; </b> weatherStation = <b>null; </b> <b>} </b> <b>

}

</b> <i>//------------------------------------------------------------- </i> <i>/** Peform the read on the WeatherStation * * @parameter event reported event */ </i> <b>public</b> <b>void</b> actionPerformed<b>(</b>ActionEvent event<b>)</b> <b>{ </b> <i>// stop the time while process so events don't stack up </i> weatherPanel<b>.</b>readWeatherStationTimer<b>.</b>stop<b>

();

</b> <i>// check for no weather station found </i> <b>if</b> <b>(</b>weatherStation == <b>null) </b> weatherPanel<b>.</b>updateWeather<b>(null,</b> lastError<b>

);

</b> <i>// make reading of weather station and check result </i> <b>if</b> <b>(</b>weatherStation<b>.</b>makeReading<b>())</b> <b>{ </b> <i>// send back the result to the panel for visual update </i> weatherPanel<b>.</b>updateWeather<b>(</b>weatherStation<b>,</b> lastError<b>); </b> <b>}</b> <b>else</b> <b>{ </b> <i>// get the error found </i> lastError = weatherStation<b>.</b>getLastErrorAsString<b>

();

</b> <i>// report error </i> weatherPanel<b>.</b>updateWeather<b>(null,</b> lastError<b>); </b> <b>

}

</b> <i>// restore the timer </i> weatherPanel<b>.</b>readWeatherStationTimer<b>.</b>start<b>(); </b> <b>

}

</b> <i>//------------------------------------------------------------- </i> <i>/** Find the first valid ibutton adapter by using the iButton Access * Provider and enumerating all adapter types and ports. Provide * output to standard out during the search. * * @parameter adapter adapter reference to return the valid adapter in * * @return 'true' if a valid adapter was found else 'false' */ </i> <b>public</b> <b>static</b> DSPortAdapter findFirstValidAdapter<b>()</b> <b>{ </b> <i>// create an iButton Access Provider </i> iButtonAccessProvider ibap = <b>new</b> iButtonAccessProvider<b>

();

</b> <i>// enumerate through each of the adapter classes </i> <b>for</b> <b>(</b>Enumeration adapter_enum = ibap<b>.</b>enumerateAllAdapters<b>(); </b> adapter_enum<b>.</b>hasMoreElements<b>();)</b> <b>{ </b> <i>// cast the enum as a DSPortAdapter </i> DSPortAdapter adapter = <b>(</b>DSPortAdapter<b>)</b> adapter_enum<b>.</b>nextElement<b>

();

</b> <i>// get the port names we can use and try to open, test and close each </i> <b>for</b> <b>(</b>Enumeration port_name_enum = adapter<b>.</b>getPortNames<b>(); </b> port_name_enum<b>.</b>hasMoreElements<b>();)</b> <b>{ </b> <i>// get the next port name </i> String port_name = <b>(</b>String<b>)</b> port_name_enum<b>.</b>nextElement<b>

();

</b> <i>// If this application 'hangs' on a COM port, add one or more of the </i> <i>// following lines to skip the offending port </i> <i>// </i> <i>// if ((port_name.compareTo("COM1") == 0)) </i> <i>// continue; </i> <i>// if ((port_name.compareTo("COM2") == 0)) </i> <i>// continue; </i> <i>// if ((port_name.compareTo("COM3") == 0)) </i> <i>// continue; </i> <i>// if ((port_name.compareTo("COM4") == 0)) </i> <i>

// continue;

</i> <i>// select the port, and try to detect the adapter on it </i> <b>try</b> <b>{ </b> <i>// select the port </i> <b>if</b> <b>(!</b>adapter<b>.</b>selectPort<b>(</b>port_name<b>)) </b> <b>

continue;

</b> <i>// check for the adapter </i> <b>if</b> <b>(</b>adapter<b>.</b>adapterDetected<b>()) </b> <b>return</b> adapter<b>; </b> <b>else</b> <b>{ </b> adapter<b>.</b>freePort<b>(); </b> <b>continue; </b> <b>} </b> <b>}</b> <b>catch</b> <b>(</b>Exception e<b>)</b> <b>{ </b> System<b>.</b>err<b>.</b>println<b>(</b>"Exception on selectport: " + e<b>); </b> <b>

}

</b> <b>}</b> <i>

// port enumeration

</i> <b>}</b> <i>

// adapter enumeration

</i> <i>// valid adapter not found </i> <b>return</b> <b>null; </b> <b>

}

</b> <i>//------------------------------------------------------------- </i> <i>/** Read a specified text file in the current user directory and * interpret it as the string version iButtonID's separated by * the line separator. * * @parameter filename of file to read (must be in current directory) * * @return vector of iButtonID's. If there was an error reading * or interpreting the file, an empty vector is returned. */ </i> <b>public</b> <b>static</b> Vector readIDFile<b>(</b>String fileName<b>)</b> <b>{ </b> <i>// get the current direction and the file names to write </i> String dirName = System<b>.</b>getProperty<b>(</b>"user.dir"<b>)</b> + System<b>.</b>getProperty<b>(</b>"file.separator"<b>

);

</b> <i>// vectors to hold the ID's contents </i> Vector id_vector = <b>new</b> Vector<b>

();

</b> <b>try</b> <b>{ </b> <i>// create a pushback character read to get the ID strings </i> PushbackReader in = <b>new</b> PushbackReader<b>(</b> <b>new</b> BufferedReader<b>( </b> <b>new</b> FileReader<b>(</b>dirName + fileName<b>

)));

</b> <b>int</b> chr = -1<b>

;

</b> <i>// loop until end of file </i> <b>do</b> <b>{ </b> <i>// loop to get an id string </i> String id_string = ""<b>; </b> <b>while</b> <b>(</b>Character<b>.</b>isLetterOrDigit<b>((char)(</b>chr = in<b>.</b>read<b>()))) </b> id_string += <b>(char)</b> chr<b>

;

</b> <i>// create an iButtonID with this string </i> iButtonID id = <b>new</b> iButtonID<b>(</b>id_string<b>

);

</b> <i>// check for invalid ID </i> <b>if</b> <b>(!</b>id<b>.</b>isValidID<b>()) </b> <b>return</b> <b>new</b> Vector<b>

();

</b> <i>// add it to the vector </i> id_vector<b>.</b>addElement<b>((</b>iButtonID<b>)</b> id<b>

);

</b> <i>// loop to find the beginning of the next string </i> <b>do</b> <b>{ </b> chr = in<b>.</b>read<b>(); </b> <b>if</b> <b>(</b>Character<b>.</b>isLetterOrDigit<b>((char)</b> chr<b>))</b> <b>{ </b> in<b>.</b>unread<b>(</b>chr<b>); </b> <b>break; </b> <b>} </b> <b>}</b> <b>while</b> <b>(</b>chr != -1<b>) </b> <b>; </b> <b>}</b> <b>while</b> <b>(</b>chr != -1<b>) </b> <b>

;

</b> <i>// return the vector iButtonID's </i> <b>return</b> id_vector<b>; </b> <b>}</b> <b>catch</b> <b>(</b>Exception e<b>)</b> <b>{ </b> <i>// error reading the file so return a blank vector </i> <b>return</b> <b>new</b> Vector<b>(); </b> <b>} </b> <b>

}

}

</b>

Once you have built, installed, and configured the 1-wire weather station, you can use the above code segments to help you get started in using the 1-wire weather station API to build applications that capture, display, and store weather samples in a way that is useful to your particular needs.

Going forward

In this article we’ve focused on the collection of weather data as a general concept. We believe that the use of the Web as a disseminator of realtime data for processing by users is emerging; we expect to see more and more funding and projects along these lines. Although we picked weather stations for this article, you could just as easily apply these concepts to homes, factories, and offices. There are many architectural choices that can be made when building such systems.

The specific technologies discussed below are useful in building infrastructures for supporting millions of 1-wire weather stations collecting data and publishing it to the Web.

The HTTP pipe approach

HTTP pipe approaches are as old as the Web. This technology represents one of the easiest ways to get data moving to users in an unsolicited manner. There is much existing work in this area already, and you can find a weather-data implementation of this described in great detail in the Resources.

XML

XML is a powerful new emerging standard that allows developers to practice modern software engineering. In future articles we will propose some XML tags for the weather data. These tags should include the date, time, latitude/longitude, elevation, and standard names as well as a dictionary. Tagging weather data in XML allows it to be exchanged easily and used in other programs for visual and analytical use. We are soliciting input from meteorologists about what a solid definition of a weather data sample would need. If you are a meteorologist and are interested in this, please contact us. Or if you have XML tagging ideas, feel free to submit them to one or both of us.

As mentioned earlier, using XML to define data formats would allow weather stations and users of the data to communicate more effectively with less code rewriting and interfaces. With XML, you can clearly separate the data from the representation of the data. This article will include an example of some advanced XML for studying weather.

At this time it isn’t clear if there are existing XML definitions for weather sample data.

Data security and sale

Some individuals sell weather data on the Web today. You can find a description of one such individual in the Resources. While selling weather data may not be palatable to everyone, from the standpoint of electronic commerce, you could add this to the architecture using some of the concepts discussed in previous articles on the Java card. For example, you could require one token to be put on your Java card for every 24 hours of data. To convert the tokens to some other valuable commodity, you would go to the Token Exchange Web site and convert them.

Depending on the requirements of your application or your customers, security solutions can easily be added to the weather stations. Here are some methods for adding security:

  • Use smart cards to sign the data
  • Use smart cards to authenticate data
  • Pay users for signed authenticated data
  • Provide secure remote access to weather stations using smart cards

Three-dimensional data stores

What is the best way to store weather data locally when you only have one station at a specific location or when you have millions of them scattered throughout a large region? Traditionally, data storage is associated with an RDBMS. Many scientific types of applications, however, have data types that are not well-suited to a traditional RDBMS. As time goes on and object technology becomes more pervasive, the role of the RDBMS will diminish, unless the RDBMS provides good support for objects. We will focus on Java object stores rather than an RDBMS.

Multicasting of weather data

In earlier JavaWorld articles, we discussed Java reliable multicast. Multicasting of weather data with a global positioning system (GPS), you can tune to channels automatically, depending on what region you’re in. The point of this article is to be practical in showing you how to build systems, but it is important to think outside the box and consider how the Web and devices can be put together to provide new types of services.

Jini

By defining protocols that can be easily implemented, weather stations and users interested in them can easily identify each other and establish communication. Consider the following application that Jini makes relatively easy to implement from a software perspective. We must warn you that the devices for doing this are still expensive. But consider what will happen when you can buy a 5 part that connects some device to the Internet and makes it Web-addressable. Suppose your realtime devices have wireless proximity transmitters on them and as you approach different ones, they automatically set up and tear down a small network around you. Effectively, you get realtime data from different sources as you move through space — not literally but as a car would going down the highway.

Jini provides the following specific services with very little effort:

  • Locating weather stations (lookup service)
  • Ability of a weather stations (attributes)
  • Communication interface to the weather station (RMI downloading)
  • Asynchronous broadcasts events from weather stations (abnormal readings)

Supporting weather stations with a Jini services API renders the weather stations vendor-neutral. We’ll show you how to do this next month.

Publishing data from a weather station to the Web

Rinaldo has a weather station in his back yard at Lat/Lon 41.222093, -73.317894 elevation sea level. You can read the data there by clicking on the URL in the Resources. There are many more commands and features of this architecture that will be discussed in future articles. You will be able to replicate the environment above if you wish to.

Please direct any comments and/or feedback on the topic areas listed immediately above and on the specific material presented in this current article to us, using the e-mail link in the bio below. Or, contact the 1-wire weather station interest group hosted by Dallas Semiconductor. To join the interest group, just e-mail weather-request@ibutton.com with the following message in the body: subscribe weather. Then send your e-mail to weather@ibutton.com.

Conclusion

A new area of buzz on the Web started by Jini has been the area of home automation from a browser. Home automation refers to remote control of light switches, electrical outlets — effectively any device that uses AC power. Some of the producers of set-top boxes are starting to discuss products that allow you to dim the lights from your couch, turn on the pool filter, turn off the computer you left on downstairs, and so on in the home consumer space. The applications in the process-control industry, which, loosely speaking, are industrial plants where goods and services are produced, can utilize this technology extensively. These applications, however, require more technical depth than we’ll get into in this article. We have demonstrated how to make realtime devices available on the Web using servlet technology. In the next article, we’ll introduce a new approach that is gaining lots of momentum: embeddable Web servers on very small devices.

Rinaldo Di Giorgio has been involved in the creation of a smart card URL programming interface to smart cards that integrates OpenCard with the Web. He is also working on a Jini-aware Java card infrastructure and technology for easily interfacing other devices such as X10 and weather stations to the Web. Rinaldo has been working with Java card technology for three years. He is currently writing a book on Java card and is a regular columnist for JavaWorld. Brian Hindman lives in Lewisville, TX and is a father-to-be. For the past four years, Brian has been working as a software engineer for Dallas Semiconductor. He is currently working on research and development projects interfacing the iButton product line with Java (http://www.ibutton.com).