diff -Naur open2300-1.10/check_rapidfire.sh open2300-1.10.patched2/check_rapidfire.sh --- open2300-1.10/check_rapidfire.sh 1970-01-01 01:00:00.000000000 +0100 +++ open2300-1.10.patched2/check_rapidfire.sh 2007-07-25 07:30:42.000000000 +0100 @@ -0,0 +1,12 @@ +#!/bin/bash + + +CHECKIT=`find /tmp -name weather.stamp -mmin -5` + +if [ "$CHECKIT" = "" ]; then + ## means its not running and updating, kill it! + echo "KILL" + KILLIT=`killall -9 wu2300_RapidFire` +else + echo "OK" +fi diff -Naur open2300-1.10/INSTALL open2300-1.10.patched2/INSTALL --- open2300-1.10/INSTALL 2005-02-28 17:37:54.000000000 +0000 +++ open2300-1.10.patched2/INSTALL 2007-07-25 09:15:28.000000000 +0100 @@ -83,6 +83,9 @@ The pgsql2300 is built using 'make pgsql2300'. It is only available for Linux. +The wu2300_RapidFire_MySQL also will not install via the 'make all' so you must +compile this directly by running 'make wu2300_RapidFire_MySQL' + The files in the htdocs directory is a simple PHP page. It will run on any webserver that runs PHP. Just copy the files to your web document tree. It assumes the binary fetch2300 to be in /usr/local/bin. Just change the path diff -Naur open2300-1.10/linux2300.c open2300-1.10.patched2/linux2300.c --- open2300-1.10/linux2300.c 2005-03-05 08:26:58.000000000 +0000 +++ open2300-1.10.patched2/linux2300.c 2007-08-05 20:27:53.000000000 +0100 @@ -241,19 +241,26 @@ * Action: Send a http request to Weather Underground * ********************************************************************/ -int http_request_url(char *urlline) +int http_request_url(char *urlline, int *rapidfire) { int sockfd; struct hostent *hostinfo; struct sockaddr_in urladdress; char buffer[1024]; int bytes_read; - - if ( (hostinfo = gethostbyname(WEATHER_UNDERGROUND_BASEURL)) == NULL ) - { - perror("Host not known by DNS server or DNS server not working"); - return(-1); - } + if (rapidfire == 1) { + if ( (hostinfo = gethostbyname(WEATHER_UNDERGROUND_BASEURL_RAPIDFIRE)) == NULL ) + { + perror("Host not known (rapid fire) by DNS server or DNS server not working"); + return(-1); + }; + } else { + if ( (hostinfo = gethostbyname(WEATHER_UNDERGROUND_BASEURL)) == NULL ) + { + perror("Host not known by DNS server or DNS server not working"); + return(-1); + }; + }; if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { @@ -272,7 +279,12 @@ perror("Cannot connect to host"); return(-1); } - sprintf(buffer, "GET %s\nHTTP/1.0\n\n", urlline); + // sprintf(buffer, "GET %s\nHTTP/1.0\n\n", urlline); + if (rapidfire == 1) { + sprintf(buffer, "GET %s HTTP/1.0\r\nUser-Agent: open2300/1.10-2\r\nAccept: */*\r\nHost: %s\r\nConnection: Keep-Alive\r\n\r\n", urlline, WEATHER_UNDERGROUND_BASEURL_RAPIDFIRE); + } else { + sprintf(buffer, "GET %s HTTP/1.0\r\nUser-Agent: open2300/1.10-2\r\nAccept: */*\r\nHost: %s\r\nConnection: Keep-Alive\r\n\r\n", urlline, WEATHER_UNDERGROUND_BASEURL); + }; send(sockfd, buffer, strlen(buffer), 0); /* While there's data, read and print it */ diff -Naur open2300-1.10/Makefile open2300-1.10.patched2/Makefile --- open2300-1.10/Makefile 2005-03-15 07:14:48.000000000 +0000 +++ open2300-1.10.patched2/Makefile 2007-07-25 07:56:28.000000000 +0100 @@ -23,6 +23,7 @@ LOGOBJ = log2300.o rw2300.o linux2300.o win2300.o FETCHOBJ = fetch2300.o rw2300.o linux2300.o win2300.o WUOBJ = wu2300.o rw2300.o linux2300.o win2300.o +WUROBJ = wu2300_RapidFire.o rw2300.o linux2300.o win2300.o mysql2300.o CWOBJ = cw2300.o rw2300.o linux2300.o win2300.o DUMPOBJ = dump2300.o rw2300.o linux2300.o win2300.o HISTOBJ = history2300.o rw2300.o linux2300.o win2300.o @@ -46,7 +47,7 @@ ####### Build rules -all: open2300 dump2300 log2300 fetch2300 wu2300 cw2300 history2300 histlog2300 bin2300 xml2300 light2300 interval2300 minmax2300 +all: open2300 dump2300 log2300 fetch2300 wu2300 wu2300_RapidFire cw2300 history2300 histlog2300 bin2300 xml2300 light2300 interval2300 minmax2300 open2300 : $(OBJ) $(CC) $(CFLAGS) -o $@ $(OBJ) $(CC_LDFLAGS) @@ -62,7 +63,13 @@ wu2300 : $(WUOBJ) $(CC) $(CFLAGS) -o $@ $(WUOBJ) $(CC_LDFLAGS) $(CC_WINFLAG) - + +wu2300_RapidFire_MySQL: + $(CC) $(CFLAGS) -o wu2300_RapidFire_MySQL wu2300_RapidFire_MySQL.c rw2300.c linux2300.c $(CC_LDFLAGS) $(CC_WINFLAG) -I/usr/include/mysql -L/usr/lib/mysql -lmysqlclient + +wu2300_RapidFire: + $(CC) $(CFLAGS) -o wu2300_RapidFire wu2300_RapidFire.c rw2300.c linux2300.c $(CC_LDFLAGS) $(CC_WINFLAG) + cw2300 : $(CWOBJ) $(CC) $(CFLAGS) -o $@ $(CWOBJ) $(CC_LDFLAGS) $(CC_WINFLAG) @@ -100,6 +107,7 @@ $(INSTALL) log2300 $(bindir) $(INSTALL) fetch2300 $(bindir) $(INSTALL) wu2300 $(bindir) + $(INSTALL) wu2300_RapidFire $(bindir) $(INSTALL) cw2300 $(bindir) $(INSTALL) histlog2300 $(bindir) $(INSTALL) xml2300 $(bindir) @@ -108,10 +116,10 @@ $(INSTALL) minmax2300 $(bindir) uninstall: - rm -f $(bindir)/open2300 $(bindir)/dump2300 $(bindir)/log2300 $(bindir)/fetch2300 $(bindir)/wu2300 $(bindir)/cw2300 $(bindir)/xml2300 $(bindir)/light2300 $(bindir)/interval2300 $(bindir)/minmax2300 + rm -f $(bindir)/open2300 $(bindir)/dump2300 $(bindir)/log2300 $(bindir)/fetch2300 $(bindir)/wu2300 $(bindir)/wu2300_RapidFire $(bindir)/cw2300 $(bindir)/xml2300 $(bindir)/light2300 $(bindir)/interval2300 $(bindir)/minmax2300 clean: - rm -f *~ *.o open2300 dump2300 log2300 fetch2300 wu2300 cw2300 history2300 histlog2300 bin2300 xml2300 mysql2300 pgsql2300 light2300 interval2300 minmax2300 + rm -f *~ *.o open2300 dump2300 log2300 fetch2300 wu2300 wu2300_RapidFire cw2300 history2300 histlog2300 bin2300 xml2300 mysql2300 pgsql2300 light2300 interval2300 minmax2300 cleanexe: - rm -f *~ *.o open2300.exe dump2300.exe log2300.exe fetch2300.exe wu2300.exe cw2300.exe history2300.exe histlog2300.exe bin2300.exe xml2300.exe mysql2300.exe pgsql2300.exe light2300.exe interval2300.exe minmax2300.exe \ No newline at end of file + rm -f *~ *.o open2300.exe dump2300.exe log2300.exe fetch2300.exe wu2300.exe wu2300_RapidFire.exe cw2300.exe history2300.exe histlog2300.exe bin2300.exe xml2300.exe mysql2300.exe pgsql2300.exe light2300.exe interval2300.exe minmax2300.exe diff -Naur open2300-1.10/open2300-dist.conf open2300-1.10.patched2/open2300-dist.conf --- open2300-1.10/open2300-dist.conf 2005-02-27 15:44:56.000000000 +0000 +++ open2300-1.10.patched2/open2300-dist.conf 2007-07-24 12:31:31.000000000 +0100 @@ -51,6 +51,11 @@ WEATHER_UNDERGROUND_ID WUID # ID received from Weather Underground WEATHER_UNDERGROUND_PASSWORD WUPASSWORD # Password for Weather Underground +#### WEATHER UNDERGROUND rapidfire configuration parameters (used by wu2300_RapidFire) +WURAPIDFIRE_MYSQLLOG 1 # Set to 1 to automatically log to MySQL using parameters below (mysql2300) +WURAPIDFIRE_TOUCHFILE 1 # Set to 1 to automatically 'touch' a file on each loop (use it to check process isn't stale) +WURAPIDFIRE_TOUCHFILENAME /tmp/weather.stamp # filename is TOUCHFILE is set to 1 + ### MYSQL Settings (only used by mysql2300) @@ -63,3 +68,4 @@ #PGSQL_CONNECT hostaddr='127.0.0.1'dbname='open2300'user='postgres'password='sql' # Connection string #PGSQL_TABLE weather # Table name #PGSQL_STATION open2300 # Unique station id + diff -Naur open2300-1.10/README open2300-1.10.patched2/README --- open2300-1.10/README 2005-02-28 17:35:42.000000000 +0000 +++ open2300-1.10.patched2/README 2007-07-25 09:09:49.000000000 +0100 @@ -71,6 +71,28 @@ You will then receive an ID and a password. This ID and password must be added to the config file (open2300.conf) before the program is used. +wu2300_RapidFire is a modification of the original wu2300. This fetches data +in a continuous loop from the weather station and will upload them to the +Rapid Fire system at Weather Underground. It will also send normal update +to WU as per wu2300 (which their documentation still suggests). +I have included a script (check_rapidfire.sh), that permits you to test +the 'touchfile' age. If the touchfile is older than 5 minutes, it will +kill the current process. This is because from time to time the +serial/upload hangs and will just lock the process. +Simply cron the check_rapidfire.sh script every 30 minutes or so to make +sure your process hasn't hung. You will also need to run the wu2300_RapidFire +script in a shell loop, so after check_rapidfire.sh has killed the process, +it will be restarted. More shell scripts are beyond the scope of these docs +but get in touch if you need any assistance. + +wu2300_RapidFire_MySQL is a further modification of the RapidFire patch +that will log to MySQL automatically at each iteration of the upload +loop. As with the mysql2300 script the program requires that MySQL client +library and header files are installed. +This is NOT compiled automatically (by make or make all), and must be +explicitly compiled: + make wu2300_RapidFire_MySQL +Other than that, it is functional the same as the above wu2300_RapidFire. cw2300 was added in 1.2. This again is a version of fetch2300 which fetched current data from the weather station and sends it to the Citizen Weather @@ -301,4 +323,4 @@ used on the webpage to show forecast and tendency. Kenneth Lavrsen -kenneth@lavrsen.dk \ No newline at end of file +kenneth@lavrsen.dk diff -Naur open2300-1.10/rw2300.c open2300-1.10.patched2/rw2300.c --- open2300-1.10/rw2300.c 2005-03-05 08:19:30.000000000 +0000 +++ open2300-1.10.patched2/rw2300.c 2007-07-24 12:31:31.000000000 +0100 @@ -2416,6 +2416,9 @@ strcpy(config->pgsql_connect, "hostaddr='127.0.0.1'dbname='open2300'user='postgres'"); // connection string strcpy(config->pgsql_table, "weather"); // PgSQL table name strcpy(config->pgsql_station, "open2300"); // Unique station id + config->weather_underground_rapidfire_mysqllog = 0; + config->weather_underground_rapidfire_touchfile = 0; + strcpy(config->weather_underground_rapidfire_touchfilename, "/tmp/weather.stamp"); // open the config file @@ -2490,6 +2493,24 @@ continue; } + if ((strcmp(token,"WURAPIDFIRE_MYSQLLOG")==0)&&(strlen(val)!=0)) + { + config->weather_underground_rapidfire_mysqllog = atoi(val); + continue; + } + + if ((strcmp(token,"WURAPIDFIRE_TOUCHFILE")==0)&&(strlen(val)!=0)) + { + config->weather_underground_rapidfire_touchfile = atoi(val); + continue; + } + + if ((strcmp(token,"WURAPIDFIRE_TOUCHFILENAME")==0)&&(strlen(val)!=0)) + { + strcpy(config->weather_underground_rapidfire_touchfilename, val); + continue; + } + if ((strcmp(token,"TIMEZONE")==0) && (strlen(val) != 0)) { strcpy(config->timezone, val); diff -Naur open2300-1.10/rw2300.h open2300-1.10.patched2/rw2300.h --- open2300-1.10/rw2300.h 2005-03-05 08:29:13.000000000 +0000 +++ open2300-1.10.patched2/rw2300.h 2007-07-24 12:31:31.000000000 +0100 @@ -51,6 +51,8 @@ /* ONLY EDIT THESE IF WEATHER UNDERGROUND CHANGES URL */ #define WEATHER_UNDERGROUND_BASEURL "weatherstation.wunderground.com" #define WEATHER_UNDERGROUND_PATH "/weatherstation/updateweatherstation.php" +#define WEATHER_UNDERGROUND_BASEURL_RAPIDFIRE "rtupdate.wunderground.com" +#define WEATHER_UNDERGROUND_PATH_RAPIDFIRE "/weatherstation/updateweatherstation.php" #define WEATHER_UNDERGROUND_SOFTWARETYPE "open2300%20v" @@ -84,6 +86,9 @@ char pgsql_connect[128]; char pgsql_table[25]; char pgsql_station[25]; + int weather_underground_rapidfire_mysqllog; // 1 or 0 to enable automatic mysql logging + int weather_underground_rapidfire_touchfile; // 1 or 0 to enable touchfile + char weather_underground_rapidfire_touchfilename[100]; // touchfilename }; struct timestamp @@ -305,7 +310,7 @@ int write_device(WEATHERSTATION serdevice, unsigned char *buffer, int size); void sleep_short(int milliseconds); void sleep_long(int seconds); -int http_request_url(char *urlline); +int http_request_url(char *urlline, int *rapidfire); int citizen_weather_send(struct config_type *config, char *datastring); #endif /* _INCLUDE_RW2300_H_ */ diff -Naur open2300-1.10/VERSIONS open2300-1.10.patched2/VERSIONS --- open2300-1.10/VERSIONS 2005-03-05 08:37:09.000000000 +0000 +++ open2300-1.10.patched2/VERSIONS 2007-07-24 12:35:10.000000000 +0100 @@ -241,8 +241,13 @@ - Change the Windows version so that those compiled for no shell window will still print messages if shell window already open. Contribution for this welcome. Just a hint by email. - - - - +1.10_rapidfire 2007 July 23 - Andy Brown - andy @ thebmwz3.co.uk + Added the wu2300_RapidFire option, to permit 3 second uploads to the + Weather Underground servers. + Note that this will open and lock the serial port whilst the application + is running, and at present it doesn't handle the port going away in a + very nice fasion. + I've made some changes to the open2300-dist.conf so if you use the + wu2300_RapidFire you will need to configure these elements. + diff -Naur open2300-1.10/wu2300.c open2300-1.10.patched2/wu2300.c --- open2300-1.10/wu2300.c 2005-03-05 08:28:35.000000000 +0000 +++ open2300-1.10.patched2/wu2300.c 2007-07-24 12:31:31.000000000 +0100 @@ -39,8 +39,8 @@ /* START WITH URL, ID AND PASSWORD */ sprintf(urlline, "http://%s%s?ID=%s&PASSWORD=%s", - WEATHER_UNDERGROUND_BASEURL,WEATHER_UNDERGROUND_PATH, - config.weather_underground_id,config.weather_underground_password); + WEATHER_UNDERGROUND_BASEURL,WEATHER_UNDERGROUND_PATH, + config.weather_underground_id,config.weather_underground_password); /* GET DATE AND TIME FOR URL */ @@ -69,6 +69,12 @@ /* READ WIND SPEED AND DIRECTION - miles/hour for Weather Underground */ + if (wind_current(ws2300, MILES_PER_HOUR, &tempfloat) > 100) + { + printf("wu2300 ERROR : Wind speed above 100 mph\n"); + exit(1); + }; + sprintf(urlline,"%s&windspeedmph=%.2f", urlline, wind_current(ws2300, MILES_PER_HOUR, &tempfloat) ); sprintf(urlline,"%s&winddir=%.1f", urlline, tempfloat); @@ -106,7 +112,7 @@ } else { - http_request_url(urlline); + http_request_url(urlline, 0); } return(0); diff -Naur open2300-1.10/wu2300_RapidFire.c open2300-1.10.patched2/wu2300_RapidFire.c --- open2300-1.10/wu2300_RapidFire.c 1970-01-01 01:00:00.000000000 +0100 +++ open2300-1.10.patched2/wu2300_RapidFire.c 2007-08-05 20:26:27.000000000 +0100 @@ -0,0 +1,196 @@ +/* open2300 - wu2300_RapidFire.c + * + * Version 1.10:patched + * + * Control WS2300 weather station + * + * Copyright 2004-2005, Kenneth Lavrsen + * Weather Underground RapidFire by Andy Brown andy @ thebmwz3.co.uk + * This program is published under the GNU General Public license + */ + +#define DEBUG 0 // wu2300_RapidFire stops writing to standard out if setting this to 0 + +#include "rw2300.h" + +/********** MAIN PROGRAM ************************************************ + * + * This program reads all current weather data from a WS2300 + * and sends it to Weather Underground using the new Rapid Fire interface + * + * It takes one parameter which is the config file name with path + * If this parameter is omitted the program will look at the default paths + * See the open2300.conf-dist file for info + * + ***********************************************************************/ +int main(int argc, char *argv[]) +{ + WEATHERSTATION ws2300; + unsigned char logline[3000] = ""; + struct config_type config; + unsigned char urlline[3000] = ""; + unsigned char urlline2[3000] = ""; + char datestring[50]; //used to hold the date stamp for the log file + char datestring2[50]; //used to hold the date stamp for the log file + double tempfloat; + time_t basictime; + int runforever; + const char *directions[]= {"N","NNE","NE","ENE","E","ESE","SE","SSE", + "S","SSW","SW","WSW","W","WNW","NW","NNW"}; + double winddir[6]; + int tempint; + int loopcounter; + char tendency[15]; + char forecast[15]; + char query[4096]; + FILE *touchfile; + +if (DEBUG) { + printf("Loading configuration\n"); +}; + + get_configuration(&config, argv[1]); + +if (DEBUG) { + printf("Configuration loaded\n"); +}; + + /* Loop should start here */ + runforever = 1; + loopcounter = 0; + + while (runforever == 1) { + + ws2300 = open_weatherstation(config.serial_device_name); + + /* START WITH URL, ID AND PASSWORD */ + + /* Normal updates url is held in urlline2 */ + + sprintf(urlline, "%s?realtime=1&rtfreq=5&rtupdate=1&action=updateraw&ID=%s&PASSWORD=%s", + WEATHER_UNDERGROUND_PATH_RAPIDFIRE, + config.weather_underground_id,config.weather_underground_password); + + /* Weather underground states at present we should stil send in normal updates to the regular URL, which is what urlline2is for */ + + sprintf(urlline2, "%s?ID=%s&PASSWORD=%s", + WEATHER_UNDERGROUND_PATH, + config.weather_underground_id,config.weather_underground_password); + + + /* GET DATE AND TIME FOR URL */ + time(&basictime); + basictime = basictime - atof(config.timezone) * 60 * 60; + strftime(datestring,sizeof(datestring),"&dateutc=%Y-%m-%d+%H%%3A%M%%3A%S", + localtime(&basictime)); + strftime(datestring2,sizeof(datestring2),"&dateutc=%Y-%m-%d+%H%%3A%M%%3A%S", + localtime(&basictime)); + sprintf(urlline, "%s%s", urlline, datestring2); + sprintf(urlline2, "%s%s", urlline2, datestring); + + + /* READ TEMPERATURE OUTDOOR - deg F for Weather Underground */ + + sprintf(urlline, "%s&tempf=%.2f", urlline, + temperature_outdoor(ws2300, FAHRENHEIT) ); + sprintf(urlline2, "%s&tempf=%.2f", urlline2, + temperature_outdoor(ws2300, FAHRENHEIT) ); + + + /* READ DEWPOINT - deg F for Weather Underground*/ + + sprintf(urlline, "%s&dewptf=%.2f", urlline, dewpoint(ws2300, FAHRENHEIT) ); + sprintf(urlline2, "%s&dewptf=%.2f", urlline2, dewpoint(ws2300, FAHRENHEIT) ); + + + + /* READ RELATIVE HUMIDITY OUTDOOR */ + + sprintf(urlline, "%s&humidity=%d", urlline, humidity_outdoor(ws2300) ); + sprintf(urlline2, "%s&humidity=%d", urlline2, humidity_outdoor(ws2300) ); + + + /* READ WIND SPEED AND DIRECTION - miles/hour for Weather Underground */ + + if (wind_current(ws2300, MILES_PER_HOUR, &tempfloat) > 100) + { + printf("wu2300 ERROR : Wind speed above 100 mph\n"); + exit(1); + }; + + sprintf(urlline,"%s&windspeedmph=%.2f", urlline, + wind_current(ws2300, MILES_PER_HOUR, &tempfloat)); + sprintf(urlline,"%s&windgustmph=%.2f", urlline, + wind_current(ws2300, MILES_PER_HOUR, &tempfloat)); + sprintf(urlline2,"%s&windspeedmph=%.2f", urlline2, + wind_current(ws2300, MILES_PER_HOUR, &tempfloat) ); + + sprintf(urlline,"%s&winddir=%.1f", urlline, tempfloat); + sprintf(urlline2,"%s&winddir=%.1f", urlline2, tempfloat); + + + /* READ RAIN 1H - inches for Weather Underground */ + + sprintf(urlline,"%s&rainin=%.2f", urlline, rain_1h(ws2300, INCHES) ); + sprintf(urlline2,"%s&rainin=%.2f", urlline2, rain_1h(ws2300, INCHES) ); + + + /* READ RAIN 24H - inches for Weather Underground */ + + sprintf(urlline,"%s&dailyrainin=%.2f", urlline, rain_24h(ws2300, INCHES) ); + sprintf(urlline2,"%s&dailyrainin=%.2f", urlline2, rain_24h(ws2300, INCHES) ); + + + /* READ RELATIVE PRESSURE - Inches of Hg for Weather Underground */ + + sprintf(urlline,"%s&baromin=%.3f",urlline, + rel_pressure(ws2300, INCHES_HG) ); + sprintf(urlline2,"%s&baromin=%.3f",urlline2, + rel_pressure(ws2300, INCHES_HG) ); + + /* Add junk that we dont need */ + sprintf(urlline,"%s&weather=CLR&clouds=CLR", urlline); + + + /* ADD SOFTWARE TYPE AND ACTION */ + sprintf(urlline,"%s&softwaretype=open2300:1.10patched",urlline); + + sprintf(urlline2,"%s&softwaretype=%s%s&action=updateraw",urlline2, + WEATHER_UNDERGROUND_SOFTWARETYPE,VERSION); + + + if (DEBUG) + { + printf("%s\n",urlline); + }; + http_request_url(urlline, 1); + + if (loopcounter == 5) { + if (DEBUG) { + printf("%s\n",urlline2); + }; + http_request_url(urlline2, 0); + loopcounter = 0; + } else { + loopcounter = loopcounter + 1; + }; + + + close_weatherstation(ws2300); + + if (config.weather_underground_rapidfire_touchfile) { + /* touch keepalive file */ + if((touchfile = fopen (config.weather_underground_rapidfire_touchfilename, "w")) != (FILE *)0) { + fputc("a", touchfile); + fclose(touchfile); + } else { + return(0); + } + }; + + /* Loop should end here */ + }; + + return(0); +} + diff -Naur open2300-1.10/wu2300_RapidFire_MySQL.c open2300-1.10.patched2/wu2300_RapidFire_MySQL.c --- open2300-1.10/wu2300_RapidFire_MySQL.c 1970-01-01 01:00:00.000000000 +0100 +++ open2300-1.10.patched2/wu2300_RapidFire_MySQL.c 2007-08-05 20:27:40.000000000 +0100 @@ -0,0 +1,311 @@ +/* open2300 - wu2300_RapidFire.c + * + * Version 1.10:patched + * + * Control WS2300 weather station + * + * Copyright 2004-2005, Kenneth Lavrsen + * Weather Underground RapidFire by Andy Brown andy @ thebmwz3.co.uk + * This program is published under the GNU General Public license + */ + +#define DEBUG 0 // wu2300_RapidFire stops writing to standard out if setting this to 0 + +#include +#include "rw2300.h" + +/********** MAIN PROGRAM ************************************************ + * + * This program reads all current weather data from a WS2300 + * and sends it to Weather Underground using the new Rapid Fire interface + * + * It also optionally logs to MySQL at each iteration + * + * It takes one parameter which is the config file name with path + * If this parameter is omitted the program will look at the default paths + * See the open2300.conf-dist file for info + * + ***********************************************************************/ +int main(int argc, char *argv[]) +{ + WEATHERSTATION ws2300; + MYSQL mysql; + unsigned char logline[3000] = ""; + struct config_type config; + unsigned char urlline[3000] = ""; + unsigned char urlline2[3000] = ""; + char datestring[50]; //used to hold the date stamp for the log file + char datestring2[50]; //used to hold the date stamp for the log file + double tempfloat; + time_t basictime; + int runforever; + const char *directions[]= {"N","NNE","NE","ENE","E","ESE","SE","SSE", + "S","SSW","SW","WSW","W","WNW","NW","NNW"}; + double winddir[6]; + int tempint; + int loopcounter; + char tendency[15]; + char forecast[15]; + char query[4096]; + FILE *touchfile; + +if (DEBUG) { + printf("Loading configuration\n"); +}; + + get_configuration(&config, argv[1]); + +if (DEBUG) { + printf("Configuration loaded\n"); +}; + + /* Loop should start here */ + runforever = 1; + loopcounter = 0; + + while (runforever == 1) { + + ws2300 = open_weatherstation(config.serial_device_name); + + /* START WITH URL, ID AND PASSWORD */ + + /* Normal updates url is held in urlline2 */ + + sprintf(urlline, "%s?realtime=1&rtfreq=5&rtupdate=1&action=updateraw&ID=%s&PASSWORD=%s", + WEATHER_UNDERGROUND_PATH_RAPIDFIRE, + config.weather_underground_id,config.weather_underground_password); + + /* Weather underground states at present we should stil send in normal updates to the regular URL, which is what urlline2is for */ + + sprintf(urlline2, "%s?ID=%s&PASSWORD=%s", + WEATHER_UNDERGROUND_PATH, + config.weather_underground_id,config.weather_underground_password); + + + /* GET DATE AND TIME FOR URL */ + time(&basictime); + basictime = basictime - atof(config.timezone) * 60 * 60; + strftime(datestring,sizeof(datestring),"&dateutc=%Y-%m-%d+%H%%3A%M%%3A%S", + localtime(&basictime)); + strftime(datestring2,sizeof(datestring2),"&dateutc=%Y-%m-%d+%H%%3A%M%%3A%S", + localtime(&basictime)); + sprintf(urlline, "%s%s", urlline, datestring2); + sprintf(urlline2, "%s%s", urlline2, datestring); + + + /* READ TEMPERATURE OUTDOOR - deg F for Weather Underground */ + + sprintf(urlline, "%s&tempf=%.2f", urlline, + temperature_outdoor(ws2300, FAHRENHEIT) ); + sprintf(urlline2, "%s&tempf=%.2f", urlline2, + temperature_outdoor(ws2300, FAHRENHEIT) ); + + + /* READ DEWPOINT - deg F for Weather Underground*/ + + sprintf(urlline, "%s&dewptf=%.2f", urlline, dewpoint(ws2300, FAHRENHEIT) ); + sprintf(urlline2, "%s&dewptf=%.2f", urlline2, dewpoint(ws2300, FAHRENHEIT) ); + + + + /* READ RELATIVE HUMIDITY OUTDOOR */ + + sprintf(urlline, "%s&humidity=%d", urlline, humidity_outdoor(ws2300) ); + sprintf(urlline2, "%s&humidity=%d", urlline2, humidity_outdoor(ws2300) ); + + + /* READ WIND SPEED AND DIRECTION - miles/hour for Weather Underground */ + + if (wind_current(ws2300, MILES_PER_HOUR, &tempfloat) > 100) + { + printf("wu2300 ERROR : Wind speed above 100 mph\n"); + exit(1); + }; + + sprintf(urlline,"%s&windspeedmph=%.2f", urlline, + wind_current(ws2300, MILES_PER_HOUR, &tempfloat)); + sprintf(urlline,"%s&windgustmph=%.2f", urlline, + wind_current(ws2300, MILES_PER_HOUR, &tempfloat)); + sprintf(urlline2,"%s&windspeedmph=%.2f", urlline2, + wind_current(ws2300, MILES_PER_HOUR, &tempfloat) ); + + sprintf(urlline,"%s&winddir=%.1f", urlline, tempfloat); + sprintf(urlline2,"%s&winddir=%.1f", urlline2, tempfloat); + + + /* READ RAIN 1H - inches for Weather Underground */ + + sprintf(urlline,"%s&rainin=%.2f", urlline, rain_1h(ws2300, INCHES) ); + sprintf(urlline2,"%s&rainin=%.2f", urlline2, rain_1h(ws2300, INCHES) ); + + + /* READ RAIN 24H - inches for Weather Underground */ + + sprintf(urlline,"%s&dailyrainin=%.2f", urlline, rain_24h(ws2300, INCHES) ); + sprintf(urlline2,"%s&dailyrainin=%.2f", urlline2, rain_24h(ws2300, INCHES) ); + + + /* READ RELATIVE PRESSURE - Inches of Hg for Weather Underground */ + + sprintf(urlline,"%s&baromin=%.3f",urlline, + rel_pressure(ws2300, INCHES_HG) ); + sprintf(urlline2,"%s&baromin=%.3f",urlline2, + rel_pressure(ws2300, INCHES_HG) ); + + /* Add junk that we dont need */ + sprintf(urlline,"%s&weather=CLR&clouds=CLR", urlline); + + + /* ADD SOFTWARE TYPE AND ACTION */ + sprintf(urlline,"%s&softwaretype=open2300:1.10patched",urlline); + + sprintf(urlline2,"%s&softwaretype=%s%s&action=updateraw",urlline2, + WEATHER_UNDERGROUND_SOFTWARETYPE,VERSION); + + + if (DEBUG) + { + printf("%s\n",urlline); + }; + http_request_url(urlline, 1); + + if (loopcounter == 5) { + if (DEBUG) { + printf("%s\n",urlline2); + }; + http_request_url(urlline2, 1); + loopcounter = 0; + } else { + loopcounter = loopcounter + 1; + }; + + + if (config.weather_underground_rapidfire_mysqllog) { + + /* MySQL part */ + /* READ TEMPERATURE INDOOR */ + + sprintf(logline,"\'%.1f\',", temperature_indoor(ws2300, config.temperature_conv) ); + + + /* READ TEMPERATURE OUTDOOR */ + + sprintf(logline,"%s\'%.1f\',", logline, + temperature_outdoor(ws2300, config.temperature_conv) ); + + + /* READ DEWPOINT */ + + sprintf(logline,"%s\'%.1f\',", logline, + dewpoint(ws2300, config.temperature_conv) ); + + + /* READ RELATIVE HUMIDITY INDOOR */ + + sprintf(logline,"%s\'%d\',", logline, humidity_indoor(ws2300) ); + + + /* READ RELATIVE HUMIDITY OUTDOOR */ + + sprintf(logline,"%s\'%d\',", logline, humidity_outdoor(ws2300) ); + + + /* READ WIND SPEED AND DIRECTION aND WINDCHILL */ + + sprintf(logline,"%s\'%.1f\',", logline, + wind_all(ws2300, config.wind_speed_conv_factor, + &tempint, winddir) ); + + sprintf(logline,"%s\'%.1f\',\'%s\',", logline, + winddir[0], directions[tempint]); + + + /* READ WINDCHILL */ + + sprintf(logline,"%s\'%.1f\',", logline, + windchill(ws2300, config.temperature_conv) ); + + + /* READ RAIN 1H */ + + sprintf(logline,"%s\'%.1f\',", logline, + rain_1h(ws2300, config.rain_conv_factor) ); + + + /* READ RAIN 24H */ + + sprintf(logline,"%s\'%.1f\',", logline, + rain_24h(ws2300, config.rain_conv_factor) ); + + + /* READ RAIN TOTAL */ + + sprintf(logline,"%s\'%.1f\',", logline, + rain_total(ws2300, config.rain_conv_factor) ); + + + /* READ RELATIVE PRESSURE */ + + sprintf(logline,"%s\'%.1f\',", logline, + rel_pressure(ws2300, config.pressure_conv_factor) ); + + + /* READ TENDENCY AND FORECAST */ + + tendency_forecast(ws2300, tendency, forecast); + sprintf(logline,"%s\'%s\',\'%s\'", logline, tendency, forecast); + + + /* GET DATE AND TIME FOR LOG FILE, PLACE BEFORE ALL DATA IN LOG LINE */ + + time(&basictime); + strftime(datestring,sizeof(datestring), + "\'%Y%m%d%H%M%S\',\'%Y-%m-%d\',\'%H:%M:%S\'", + localtime(&basictime) ); + /* INIT MYSQL AND CONNECT */ + if(!mysql_init(&mysql)) + { + fprintf(stderr, "Cannot initialize MySQL"); + exit(0); + } + + if(!mysql_real_connect(&mysql, config.mysql_host, config.mysql_user, + config.mysql_passwd, config.mysql_database, + config.mysql_port, NULL, 0)) + { + fprintf(stderr, "%d: %s \n", + mysql_errno(&mysql), mysql_error(&mysql)); + exit(0); + } + + sprintf(query, "INSERT INTO weather VALUES (%s, %s)", datestring, logline); + + if(mysql_query(&mysql, query)) + { + fprintf(stderr, "Could not insert row. %s %d: \%s \n", query, mysql_errno(&mysql), mysql_error(&mysql)); + mysql_close(&mysql); + exit(0); + } + + mysql_close(&mysql); + + }; + + close_weatherstation(ws2300); + + if (config.weather_underground_rapidfire_touchfile) { + /* touch keepalive file */ + if((touchfile = fopen (config.weather_underground_rapidfire_touchfilename, "w")) != (FILE *)0) { + fputc("a", touchfile); + fclose(touchfile); + } else { + return(0); + } + }; + + /* Loop should end here */ + }; + + return(0); +} +