Quantcast
Channel: The Raspberry Pi Hobbyist
Viewing all articles
Browse latest Browse all 60

Log Data to the Weather Underground

$
0
0
The next topic for my weather station system is how to send your data to a "Personal Weather Station" on the Weather Underground web site. This provides a nice interface for the world to see your current (and past) conditions.

The PWS Overview explains what personal weather stations are. It also has a buying guide. For comparison, the total cost for my system was somewhere around $150 (That's just a very rough guess.)

See PWS Upload Protocol for the complete documentation for uploading data for a PWS. To summarize, you need to send a properly formatted string to a web address (a simple HTTP GET to a PHP script.)

So here is a simplified example of the code that I am using.

/***********************************************************************
Filename: wunderground.c
send current conditions to my Personal Weather Station on
The Weather Underground

Uses libcurl to send the data via HTTP

build with:
gcc -o wutest wunderground.c -L/usr/local/lib -L/usr/local/ -lcurl -lwiringPi

23-Jan-2015 Ted Hale created this as an example for blog

************************************************************************/

/* system includes */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
#include <string.h>
#include <curl/curl.h>

#define TRUE 1
#define FALSE 0

// these are normally global varables that my weather system updates
// just put them here for this example
float outsideTemp;
float windSpeed;
float windGust;
float rainPeriod;
float humidity;
float barometric;

// my PWS ID and password
char *myStationID = "KVAWILLI99";
char *myStationPassword = "NOTMYPASSWORD";

// structure used by the libcurl write callback function
struct url_data {
size_t size;
char* data;
};

//=====================================================================
// write callback function needed by libCurl
size_t write_data(void *ptr, size_t size, size_t nmemb, struct url_data *data) {
size_t index = data->size;
size_t n = (size * nmemb);
char* tmp;

data->size += (size * nmemb);
tmp = realloc(data->data, data->size + 1); /* +1 for null terminator */

if(tmp) {
data->data = tmp;
} else {
if(data->data) {
free(data->data);
}
printf("skynet_post Failed to allocate memory.\n");
return 0;
}

memcpy((data->data + index), ptr, n);
data->data[data->size] = '\0';

return size * nmemb;
}

//=====================================================================
// upload current conditions to Weather Underground
int UpdateWunderground()
{
// URL format
char *myFmt = "http://weatherstation.wunderground.com/weatherstation/updateweatherstation.php?"
// 1 2 3 4 5 6 7 8
"ID=%s&PASSWORD=%s&dateutc=%04d-%02d-%02d+%02d%%3A%02d%%3A%02d"
// 9 10 11 12
"&windspeedmph=%f&windgustmph=%f&tempf=%f&rainin=%f"
// 13 14
"&baromin=%f&humidity=%f&action=updateraw";

/* 1 ID
* 2 passwd
* 3 yr
* 4 mon
* 5 day
* 6 hr
* 7 min
* 8 sec
* 9 winspeed
* 10 gusts
* 11 Outdoor temp
* 12 rain
* 13 baro
* 14 humidity
*/

int error = TRUE;
time_t now;
struct tm *dt;
int hour,minute,second,year,month,day;
char url[1024];

CURL *curl;
CURLcode res;
struct url_data response;

time(&now);
dt = gmtime(&now);

// build the URL string
// 1 2
snprintf(url, sizeof(url)-1, myFmt, myStationID, myStationPassword,
// 3 4 5 6 7 8
dt->tm_year, dt->tm_mon, dt->tm_mday, dt->tm_hour, dt->tm_min, dt->tm_sec,
// 9 10 11 12 13 14
windSpeed, windGust, outsideTemp, rainPeriod, barometric, humidity);

// guarantee null termination of string
url[sizeof(url)-1] = 0;

curl = curl_easy_init();
if (curl) {
response.size = 0;
response.data = malloc(4096); /* reasonable size initial buffer */
response.data[0] = '\0';
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
res = curl_easy_perform(curl);
if(res != CURLE_OK)
{
printf("curl_easy_perform() failed: %s\n",curl_easy_strerror(res));
error = TRUE;
} else {
error = (strcmp(response.data,"Success") != 0);
}
curl_easy_cleanup(curl);
free (response.data);
} else {
printf("curl_easy_init failed\n");
error = TRUE;
}

return error;
}

int main()
{
// set some dummy data
outsideTemp = 69.7;
windSpeed = 2.3;
windGust = 5.6;
rainPeriod = 0.001;
humidity = 75.0;
barometric = 31.5;

UpdateWunderground();

return 0;
}

Please let me know if you use this code.  I would like to hear how it works for you.


Viewing all articles
Browse latest Browse all 60

Trending Articles