I had discovered a website a few years ago called Weather Underground www.wunderground.com. It provides data for hundreds to thousands of personal weather stations with data updated every 5-10 minutes. I had used an interface in Excel to extract the data for a project. I figured this would be a good exercise to see if I can do the same thing in LabVIEW.
I wanted to be able to plot all of the weather data such as temperture, dew point, humidity, rainfall, and some other parameters. I wanted to give the user a means to use a web browser to search the website to discover the ID code of any weather station site they might be interested in. Also, they can select the current or a historical date.
As a result of this exercise, I was able to gain some experience using ActiveX event callbacks (I had only ever used them in a NI LabVIEW training class) and also experimented with some Regex codes (which I usually avoid because it looks like a secret language.)
To be able to graph weather data for a desired date from a personal weather station of the user's choosing.
The requirement for the second round is to add a communication mechanism between independently running VI's. I decided to use the classic TCP/IP server client architecture. I started with the Named Service TCP Client and Named Service TCP Server example VI's that are packaged with LabVIEW and can be found through the Help / Find Examples menu. I had actually never looked at these specific examples before, and I discovered the named service feature which I think would have numerous advantages over using port numbers as shown in the regular Data Client and Server examples. With those, you have to determine a port number to establish as the communication link. While there are lists of available numbers, there is no guarantee that a particular number may not already be in use by some other program. While there are mechanisms to detect such problems and work around them, it still seems like a large programming hassle to discover an unused port and somehow publish it so that the client program can find it and connect to it. With the named service, you can ignore the port number and come up with a name that should be unique enough that it is very unlikely that any other program would be using it and causing a conflict.
I decided to create a VI that acts as a storage database of the collected weather data. A TCP client was added as a consumer loop to my previous VI (Weather.vi) from Round 1 of the contest. This VI will send the data to the new server VI called Weather - Database.vi. A command instruction and other data that is packaged as a variant are flattened to a string for transport through the TCP functions. The new VI stores the flattened data in a Configuration .ini file. I am using this as an easy to implement database type of file. It stores data in sections (each section represents a specific weather station) and as keys within that section (each key represents a specific date). This made it fairly easy to store the data within a file where I can later retrieve it based on station and date and let LabVIEW handle all of that work behind the scenes. A true database implementation would be better if the datafile grew too large, but for the time being, this serves my purpose. Also, if the data is updated later on, it will automatically overwrite the previous data. The new database VI was actually derived from the previous VI since it already had the front panel event handling loop.
For the purpose of this exercise, I hardcoded the IP address so that it loops back to the local host (127.0.01). Thus both VI's must run on the same PC. But one of the nice advantages of TCP/IP communication is that it is not necessary. By using the IP address or machine name of another PC, the server VI could be running on a different PC.
To be able to graph weather data for a desired date from a personal weather station of the user's choosing.
To be able to store the data collected from the web in a file format. That data can be later retrieved and viewed offline.
Round 1:
Main Front Panel:
Browser Front Panel:
Round 2:
Main Front Panel:
Server Database Front Panel:
Main Block Diagram:
Browser Block Diagram:
Round2:
Main Block Diagram:
Server Database Front Panel:
Weather.zip Round 1 VI's (Saved as LV 8.6)
Weather2.zip Round 2 VI's (Saved as LV8.6)
I use Weather Underground all the time when I fly my remote controlled airplanes. Nice work!
I was about to blow-off your code as nothing exceptional, then I saw the use of the event callback! Good work. I figured you'd be polling the site for data, but this is much more efficient and good example code. It's a shame that so much navigation must be done before clicking 'Get Data', though this is tough to automate, plus changes to their website structure could quickly break working automation code.
Thanks Grant, Thanks Mike.
The creation of a browser was about the only way I could quickly think to put something together to be able to determine a valid weather station ID code. And you're right, it would have been difficult to put something together where I could easily parse and browse web pages automatically to search for a valid code considering things might change.
Though I determined that the actual gathering of the data seemed reliable and consistent once I had the code. I first discovered the site in 2007 and did something in Excel to use it as a data source. Three and a half years later, that Excel spreadsheet still worked to get the data.
If I was going to improve this further, I'd either search for a way to programmatically get from the website all the valid station IDs and how to sort them and let the user search through them. Or I'd probably just create a list of all the sites a user has browsed for in the past and store them (rather than just the most recent search) and they could select among them or go browse for a new station.
Has this been tested with a more recent version of LabVIEW and Weather Underground API? (e.g. 2015 to now)