Here's how I upload my weather station data to Weather Underground with HTTP capable CRBasic data loggers with internet access. Figured I would create an up to date post that's a little more comprehensive than the articles dated more than a few years old:
You can find the wunderground PWS upload protocol documentation here:
https://support.weather.com/s/article/PWS-Upload-Protocol?language=en_US
Login credentials needed are the site ID and Key. Key is generated unique to the device created. These are your "username" and "password" respectively.
Variables needed for this are (those that are in use for my station):
DATE_TIME 'DATE TIME FROM 1 MINUTE OBSERVATION DATA TABLE WU_DATE_TIME 'WEATHER UNDERGROUND FORMATTED TIMESTAMP WU_HTTP 'WEATHER UNDERGROUND HTTP GET QUERY DATA HTTPRESPONSE_WU 'WEATHER UNDERGROUND HTTP GET RESPONSE
WIND_SPEED 'WIND SPEED METERS PER SECOND
WIND_DIRECTION 'WIND DIRECTION DEGREES
TEMPERATURE 'FAST RESPONSE TEMPERATURE CELSIUS
REL_HUMIDITY 'FAST RESPONSE RELATIVE HUMIDITY PERCENT
DEW_POINT 'CALCULATED DEW POINT CELSIUS
MSLP 'CALCULATED MEAN SEA-LEVEL PRESSURE HECTOPASCALS
TOTAL_PRECIP 'TOTAL PRECIPITATION INCHES
SOL_RADIATION 'SOLAR RADIATION WATTS PER METER SQUARED
1_MINUTE_TABLE, 1_HOUR_TABLE, and 1_DAY_TABLE will be the example tables used to pull data from for the WU_HTTP string.
DATE_TIME will be the string variable our 1 minute observation table time is stored. To pull this variable, we will use the SecsSince1990 instruction. Same thing will be done for our hourly and daily precipitation values.
DATE_TIME = SecsSince1990 (1_MINUTE_TABLE.Timestamp,1) 'VARIABLE FORMATTED AS STRING "MM/dd/yyyy HH:mm:ss"
From here we can split the DATE_TIME components into their respective parts:
'EXTRACT EACH DATE TIME COMPONENT FROM DATE_TIME CR1000_YEAR = Mid (DATE_TIME,7,4) 'PARSE TIME_STAMP YEAR AS STRING CR1000_MONTH = Mid (DATE_TIME,1,2) 'PARSE TIME_STAMP MONTH AS STRING CR1000_DAY = Mid (DATE_TIME,4,2) 'PARSE TIME_STAMP DAY AS STRING CR1000_HOUR = Mid (DATE_TIME,12,2) 'PARSE TIME_STAMP HOUR AS STRING CR1000_MINUTE = Mid (DATE_TIME,15,2) 'PARSE TIME_STAMP MINUTE AS STRING CR1000_SECOND = Mid (DATE_TIME,18,2) 'PARSE TIME_STAMP SECOND AS STRING
And then create the WU_DATE_TIME variable:
WU_DATE_TIME = CR1000_YEAR + "-" + CR1000_MONTH + "-" + CR1000_DAY + "+" + CR1000_HOUR + "%3A" + CR1000_MINUTE + "%3A" + CR1000_SECOND
Now to create the data string to be sent via HTTP Get query instruction:
WU_HTTP = "?ID=XXXXXXXXXXX" WU_HTTP = WU_HTTP + "&PASSWORD=XXXXXXXX" WU_HTTP = WU_HTTP + "&dateutc=" + WU_DATE_TIME WU_HTTP = WU_HTTP + "&winddir=" + 1_MINUTE_TABLE.WIND_DIRECTION_Avg(1) WU_HTTP = WU_HTTP + "&windspeedmph=" + (1_MINUTE_TABLE.WIND_SPEED_Avg(1) * 2.237) 'CONVERT MPS TO MPH WU_HTTP = WU_HTTP + "&windgustmph=" + (1_MINUTE_TABLE.WIND_SPEED_Max(1) * 2.237) 'CONVERT MPS TO MPH WU_HTTP = WU_HTTP + "&humidity=" + 1_MINUTE_TABLE.REL_HUMIDITY_Avg(1) WU_HTTP = WU_HTTP + "&dewptf=" + (1_MINUTE_TABLE.DEW_POINT_Avg(1) * 1.8 + 32) 'CONVERT C TO F WU_HTTP = WU_HTTP + "&tempf=" + (1_MINUTE_TABLE.TEMPERATURE_Avg(1) * 1.8 + 32) 'CONVERT C TO F WU_HTTP = WU_HTTP + "&rainin=" + 1_HOUR_TABLE.TOTAL_PRECIP_Tot(1) WU_HTTP = WU_HTTP + "&dailyrainin=" + 1_DAY_TABLE.TOTAL_PRECIP_Tot(1) WU_HTTP = WU_HTTP + "&baromin=" + (1_MINUTE_TABLE.MSLP_Avg(1) / 33.864) 'CONVERT HPA TO INHG WU_HTTP = WU_HTTP + "&solarradiation=" + 1_MINUTE_TABLE.SOL_RADIATION_Avg(1) WU_HTTP = WU_HTTP + "&softwaretype=CRBasic%Program.CR1%20VER%201.0" WU_HTTP = WU_HTTP + "&action=updateraw"
Using the TableName.FieldName instruction we can pull the latest record from our data tables to send via HTTP Get to Weather Underground. The suffixes are the data type saved in the table _Avg, _Max, _Tot (average, maximum, totalized).
To keep data logger variables to a minimum I elected to convert the values within the string to their required units of measurement for upload.
Now that we have our data string constructed, we can use the HTTPGet instruction to send the data each minute:
HTTPGet ("http://weatherstation.wunderground.com/weatherstation/updateweatherstation.php" + WU_HTTP,HTTPRESPONSE_WU,"",1000)
Now with everything together, the entire code snippet can be put into a SlowSequence executed each minute pulling from the 1 minute, 1 hour, and 1 day tables.
SlowSequence
Scan (1,Min,3,0)
DATE_TIME = SecsSince1990 (1_MINUTE_TABLE.Timestamp,1) 'VARIABLE FORMATTED AS STRING "MM/dd/yyyy HH:mm:ss"
'EXTRACT EACH DATE TIME COMPONENT FROM DATE_TIME
CR1000_YEAR = Mid (DATE_TIME,7,4) 'PARSE TIME_STAMP YEAR AS STRING
CR1000_MONTH = Mid (DATE_TIME,1,2) 'PARSE TIME_STAMP MONTH AS STRING
CR1000_DAY = Mid (DATE_TIME,4,2) 'PARSE TIME_STAMP DAY AS STRING
CR1000_HOUR = Mid (DATE_TIME,12,2) 'PARSE TIME_STAMP HOUR AS STRING
CR1000_MINUTE = Mid (DATE_TIME,15,2) 'PARSE TIME_STAMP MINUTE AS STRING
CR1000_SECOND = Mid (DATE_TIME,18,2) 'PARSE TIME_STAMP SECOND AS STRING
WU_HTTP = "?ID=XXXXXXXXXXX"
WU_HTTP = WU_HTTP + "&PASSWORD=XXXXXXXX"
WU_HTTP = WU_HTTP + "&dateutc=" + WU_DATE_TIME
WU_HTTP = WU_HTTP + "&winddir=" + 1_MINUTE_TABLE.WIND_DIRECTION_Avg(1)
WU_HTTP = WU_HTTP + "&windspeedmph=" + (1_MINUTE_TABLE.WIND_SPEED_Avg(1) * 2.237) 'CONVERT MPS TO MPH
WU_HTTP = WU_HTTP + "&windgustmph=" + (1_MINUTE_TABLE.WIND_SPEED_Max(1) * 2.237) 'CONVERT MPS TO MPH
WU_HTTP = WU_HTTP + "&humidity=" + 1_MINUTE_TABLE.REL_HUMIDITY_Avg(1)
WU_HTTP = WU_HTTP + "&dewptf=" + (1_MINUTE_TABLE.DEW_POINT_Avg(1) * 1.8 + 32) 'CONVERT C TO F
WU_HTTP = WU_HTTP + "&tempf=" + (1_MINUTE_TABLE.TEMPERATURE_Avg(1) * 1.8 + 32) 'CONVERT C TO F
WU_HTTP = WU_HTTP + "&rainin=" + 1_HOUR_TABLE.TOTAL_PRECIP_Tot(1)
WU_HTTP = WU_HTTP + "&dailyrainin=" + 1_DAY_TABLE.TOTAL_PRECIP_Tot(1)
WU_HTTP = WU_HTTP + "&baromin=" + (1_MINUTE)TABLE.MSLP_Avg(1) / 33.864) 'CONVERT HPA TO INHG
WU_HTTP = WU_HTTP + "&solarradiation=" + 1_MINUTE_TABLE.SOL_RADIATION_Avg(1)
WU_HTTP = WU_HTTP + "&softwaretype=CRBasic%Program.CR1%20VER%201.0"
WU_HTTP = WU_HTTP + "&action=updateraw"
HTTPGet ("http://weatherstation.wunderground.com/weatherstation/updateweatherstation.php" + WU_HTTP,HTTPRESPONSE_WU,"",1000)
NextScan
You could probably also optimize how the WU_DATE_TIME variable is made further by setting the SecsSince1990 output to option 4 "yyyy-MM-dd HH:mm:ss" and use the Replace instruction to change the "/", " ", and ":" to "-", "+", and "%3A" respectively.
Hopefully this helps in getting your CRBasic data logger reporting to Weather Underground efficiently and effectively.
Cheers
This post is under review.