David Smart / NWSWeather
Committer:
WiredHome
Date:
Sun Mar 16 20:25:34 2014 +0000
Revision:
2:eae60b64066e
Parent:
1:e077d6502c94
Child:
4:94dfdc405640
Bug fix in the get( ) method, it was incorrectly checking a return value.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 2:eae60b64066e 1 //
WiredHome 2:eae60b64066e 2 // This file contains the interface for gathering forecast from NWS.
WiredHome 2:eae60b64066e 3 //
WiredHome 2:eae60b64066e 4 // attention: This program is copyright (c) 2014 by Smartware Computing, all
WiredHome 2:eae60b64066e 5 // rights reserved.
WiredHome 2:eae60b64066e 6 //
WiredHome 2:eae60b64066e 7 // This software, and/or material is the property of Smartware Computing. All
WiredHome 2:eae60b64066e 8 // use, disclosure, and/or reproduction not specifically authorized by Smartware
WiredHome 2:eae60b64066e 9 // Computing is prohibited.
WiredHome 2:eae60b64066e 10 //
WiredHome 2:eae60b64066e 11 // This software may be freely used for non-commercial purposes, and any
WiredHome 2:eae60b64066e 12 // derivative work shall carry the original copyright. The author of
WiredHome 2:eae60b64066e 13 // a derivative work shall make clear that it is a derivative work.
WiredHome 2:eae60b64066e 14 //
WiredHome 2:eae60b64066e 15 // author David Smart, Smartware Computing
WiredHome 2:eae60b64066e 16 //
WiredHome 2:eae60b64066e 17 #include "NWSWeather.h"
WiredHome 0:4435c965d95d 18
WiredHome 2:eae60b64066e 19 //#define DEBUG "NWS "
WiredHome 2:eae60b64066e 20 // ...
WiredHome 2:eae60b64066e 21 // INFO("Stuff to show %d", var); // new-line is automatically appended
WiredHome 2:eae60b64066e 22 //
WiredHome 2:eae60b64066e 23 #if (defined(DEBUG) && !defined(TARGET_LPC11U24))
WiredHome 2:eae60b64066e 24 #define INFO(x, ...) std::printf("[INF %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 2:eae60b64066e 25 #define WARN(x, ...) std::printf("[WRN %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 2:eae60b64066e 26 #define ERR(x, ...) std::printf("[ERR %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 2:eae60b64066e 27 #else
WiredHome 2:eae60b64066e 28 #define INFO(x, ...)
WiredHome 2:eae60b64066e 29 #define WARN(x, ...)
WiredHome 2:eae60b64066e 30 #define ERR(x, ...)
WiredHome 2:eae60b64066e 31 #endif
WiredHome 0:4435c965d95d 32
WiredHome 0:4435c965d95d 33
WiredHome 1:e077d6502c94 34 static NWSWeather::XMLItem_T WeatherData[] = {
WiredHome 1:e077d6502c94 35 {"observation_time_rfc822", NWSWeather::isString},
WiredHome 1:e077d6502c94 36 {"suggested_pickup", NWSWeather::isString},
WiredHome 1:e077d6502c94 37 {"suggested_pickup_period", NWSWeather::isInt},
WiredHome 1:e077d6502c94 38 {"location", NWSWeather::isString},
WiredHome 1:e077d6502c94 39 {"weather", NWSWeather::isString},
WiredHome 1:e077d6502c94 40 {"temp_f", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 41 {"temp_c", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 42 {"relative_humidity", NWSWeather::isInt},
WiredHome 1:e077d6502c94 43 {"wind_degrees", NWSWeather::isInt},
WiredHome 1:e077d6502c94 44 {"wind_mph", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 45 {"pressure_mb", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 46 {"pressure_in", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 47 {"dewpoint_f", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 48 {"dewpoint_c", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 49 {"windchill_f", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 50 {"windchill_c", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 51 {"visibility_mi", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 52 {"icon_url_base", NWSWeather::isString},
WiredHome 1:e077d6502c94 53 {"icon_url_name", NWSWeather::isString},
WiredHome 1:e077d6502c94 54 {"latitude", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 55 {"longitude", NWSWeather::isFloat},
WiredHome 0:4435c965d95d 56 };
WiredHome 0:4435c965d95d 57
WiredHome 0:4435c965d95d 58 #define MAXPARAMLEN 23
WiredHome 0:4435c965d95d 59
WiredHome 0:4435c965d95d 60 #define WeatherItemCount (sizeof(WeatherData)/sizeof(WeatherData[0]))
WiredHome 0:4435c965d95d 61
WiredHome 0:4435c965d95d 62 NWSWeather::NWSWeather(const char * baseURL)
WiredHome 0:4435c965d95d 63 {
WiredHome 0:4435c965d95d 64 setAlternateURL(baseURL);
WiredHome 0:4435c965d95d 65 }
WiredHome 0:4435c965d95d 66
WiredHome 0:4435c965d95d 67 NWSWeather::~NWSWeather()
WiredHome 0:4435c965d95d 68 {
WiredHome 0:4435c965d95d 69 ClearWeatherRecords();
WiredHome 0:4435c965d95d 70 }
WiredHome 0:4435c965d95d 71
WiredHome 1:e077d6502c94 72 NWSWeather::NWSReturnCode_T NWSWeather::setAlternateURL(const char * baseURL)
WiredHome 0:4435c965d95d 73 {
WiredHome 0:4435c965d95d 74 if (m_baseurl)
WiredHome 0:4435c965d95d 75 free(m_baseurl);
WiredHome 0:4435c965d95d 76 m_baseurl = (char *)malloc(strlen(baseURL)+1);
WiredHome 0:4435c965d95d 77 if (m_baseurl)
WiredHome 0:4435c965d95d 78 strcpy(m_baseurl, baseURL);
WiredHome 0:4435c965d95d 79 else {
WiredHome 0:4435c965d95d 80 return nomemory;
WiredHome 0:4435c965d95d 81 }
WiredHome 0:4435c965d95d 82 ClearWeatherRecords();
WiredHome 0:4435c965d95d 83 return noerror;
WiredHome 0:4435c965d95d 84 }
WiredHome 0:4435c965d95d 85
WiredHome 0:4435c965d95d 86 uint16_t NWSWeather::count(void)
WiredHome 0:4435c965d95d 87 {
WiredHome 0:4435c965d95d 88 return WeatherItemCount;
WiredHome 0:4435c965d95d 89 }
WiredHome 0:4435c965d95d 90
WiredHome 1:e077d6502c94 91 NWSWeather::NWSReturnCode_T NWSWeather::get(const char * site, int responseSize)
WiredHome 0:4435c965d95d 92 {
WiredHome 2:eae60b64066e 93 NWSReturnCode_T retCode = nomemory;
WiredHome 2:eae60b64066e 94 char *url = NULL;
WiredHome 0:4435c965d95d 95 char *message = (char *)malloc(responseSize);
WiredHome 0:4435c965d95d 96
WiredHome 2:eae60b64066e 97 INFO("get(%s)", site);
WiredHome 2:eae60b64066e 98 if (!message)
WiredHome 2:eae60b64066e 99 ERR("no memory");
WiredHome 2:eae60b64066e 100 while (message) {
WiredHome 2:eae60b64066e 101 url = (char *)malloc(strlen(m_baseurl) + strlen(site) + 5);
WiredHome 0:4435c965d95d 102 if (url) {
WiredHome 0:4435c965d95d 103 strcpy(url, m_baseurl);
WiredHome 0:4435c965d95d 104 strcat(url, site);
WiredHome 0:4435c965d95d 105 strcat(url, ".xml");
WiredHome 2:eae60b64066e 106 INFO(" url: %s", url);
WiredHome 0:4435c965d95d 107 http.setMaxRedirections(3);
WiredHome 0:4435c965d95d 108 int ret = http.get(url, message, responseSize);
WiredHome 0:4435c965d95d 109 if (!ret) {
WiredHome 2:eae60b64066e 110 INFO("ret is %d", ret);
WiredHome 0:4435c965d95d 111 if (http.getHTTPResponseCode() >= 300 && http.getHTTPResponseCode() < 400) {
WiredHome 2:eae60b64066e 112 retCode = noerror; // redirection that was not satisfied.
WiredHome 2:eae60b64066e 113 break;
WiredHome 0:4435c965d95d 114 } else {
WiredHome 0:4435c965d95d 115 ParseWeatherXML(message);
WiredHome 2:eae60b64066e 116 retCode = noerror;
WiredHome 2:eae60b64066e 117 break;
WiredHome 0:4435c965d95d 118 }
WiredHome 0:4435c965d95d 119 } else {
WiredHome 2:eae60b64066e 120 WARN("get returned %d, no response?", ret);
WiredHome 2:eae60b64066e 121 retCode = noresponse;
WiredHome 2:eae60b64066e 122 break;
WiredHome 0:4435c965d95d 123 }
WiredHome 0:4435c965d95d 124 } else {
WiredHome 2:eae60b64066e 125 ERR("no memory");
WiredHome 2:eae60b64066e 126 retCode = nomemory;
WiredHome 2:eae60b64066e 127 break;
WiredHome 2:eae60b64066e 128 }
WiredHome 2:eae60b64066e 129 } // while(...) but configured with break for only 1 pass.
WiredHome 2:eae60b64066e 130 INFO(" ret is %d", retCode);
WiredHome 2:eae60b64066e 131 if (url)
WiredHome 2:eae60b64066e 132 free(url);
WiredHome 2:eae60b64066e 133 if (message)
WiredHome 2:eae60b64066e 134 free(message);
WiredHome 2:eae60b64066e 135 INFO(" mem freed.");
WiredHome 2:eae60b64066e 136 return retCode;
WiredHome 2:eae60b64066e 137 }
WiredHome 2:eae60b64066e 138
WiredHome 2:eae60b64066e 139
WiredHome 2:eae60b64066e 140 NWSWeather::NWSReturnCode_T NWSWeather::isUpdated(uint16_t i)
WiredHome 2:eae60b64066e 141 {
WiredHome 2:eae60b64066e 142 if (i < WeatherItemCount) {
WiredHome 2:eae60b64066e 143 if (WeatherData[i].updated)
WiredHome 2:eae60b64066e 144 return noerror;
WiredHome 2:eae60b64066e 145 else
WiredHome 2:eae60b64066e 146 return noupdate;
WiredHome 2:eae60b64066e 147 } else {
WiredHome 2:eae60b64066e 148 return badparameter;
WiredHome 2:eae60b64066e 149 }
WiredHome 2:eae60b64066e 150 }
WiredHome 2:eae60b64066e 151
WiredHome 2:eae60b64066e 152
WiredHome 2:eae60b64066e 153 NWSWeather::NWSReturnCode_T NWSWeather::isUpdated(const char * name)
WiredHome 2:eae60b64066e 154 {
WiredHome 2:eae60b64066e 155 if (name) {
WiredHome 2:eae60b64066e 156 for (int i=0; i < WeatherItemCount; i++) {
WiredHome 2:eae60b64066e 157 if (strcmp(name, WeatherData[i].name) == 0) {
WiredHome 2:eae60b64066e 158 if (WeatherData[i].updated)
WiredHome 2:eae60b64066e 159 return noerror;
WiredHome 2:eae60b64066e 160 else
WiredHome 2:eae60b64066e 161 return noupdate;
WiredHome 2:eae60b64066e 162 }
WiredHome 0:4435c965d95d 163 }
WiredHome 0:4435c965d95d 164 }
WiredHome 2:eae60b64066e 165 return badparameter;
WiredHome 0:4435c965d95d 166 }
WiredHome 0:4435c965d95d 167
WiredHome 0:4435c965d95d 168
WiredHome 1:e077d6502c94 169 NWSWeather::NWSReturnCode_T NWSWeather::getParam(uint16_t i, char *name, Value_T *value, TypeOf_T *typeis)
WiredHome 0:4435c965d95d 170 {
WiredHome 0:4435c965d95d 171 if (i < WeatherItemCount) {
WiredHome 0:4435c965d95d 172 *name = *WeatherData[i].name;
WiredHome 0:4435c965d95d 173 *value = WeatherData[i].value;
WiredHome 0:4435c965d95d 174 if (typeis)
WiredHome 0:4435c965d95d 175 *typeis = WeatherData[i].typeis;
WiredHome 0:4435c965d95d 176 return noerror;
WiredHome 0:4435c965d95d 177 } else {
WiredHome 0:4435c965d95d 178 return badparameter;
WiredHome 0:4435c965d95d 179 }
WiredHome 0:4435c965d95d 180 }
WiredHome 0:4435c965d95d 181
WiredHome 0:4435c965d95d 182
WiredHome 1:e077d6502c94 183 NWSWeather::NWSReturnCode_T NWSWeather::getParam(const char *name, Value_T *value, TypeOf_T *typeis)
WiredHome 0:4435c965d95d 184 {
WiredHome 2:eae60b64066e 185 INFO("getParam(%s)", name);
WiredHome 2:eae60b64066e 186 for (int i=0; i < WeatherItemCount; i++) {
WiredHome 2:eae60b64066e 187 //printf("Compare(%s,%s)\r\n", name, WeatherData[i].name);
WiredHome 2:eae60b64066e 188 if (strcmp(name, WeatherData[i].name) == 0) {
WiredHome 2:eae60b64066e 189 *value = WeatherData[i].value;
WiredHome 2:eae60b64066e 190 INFO("assigned value.");
WiredHome 2:eae60b64066e 191 if (typeis)
WiredHome 2:eae60b64066e 192 *typeis = WeatherData[i].typeis;
WiredHome 2:eae60b64066e 193 return noerror;
WiredHome 0:4435c965d95d 194 }
WiredHome 0:4435c965d95d 195 }
WiredHome 0:4435c965d95d 196 return badparameter;
WiredHome 0:4435c965d95d 197 }
WiredHome 0:4435c965d95d 198
WiredHome 0:4435c965d95d 199
WiredHome 0:4435c965d95d 200 void NWSWeather::ClearWeatherRecords(void)
WiredHome 0:4435c965d95d 201 {
WiredHome 0:4435c965d95d 202 int i;
WiredHome 0:4435c965d95d 203 int count = WeatherItemCount;
WiredHome 0:4435c965d95d 204
WiredHome 0:4435c965d95d 205 for (i=0; i<count; i++) {
WiredHome 0:4435c965d95d 206 switch(WeatherData[i].typeis) {
WiredHome 0:4435c965d95d 207 case isFloat:
WiredHome 0:4435c965d95d 208 WeatherData[i].value.fValue = 0.0;
WiredHome 0:4435c965d95d 209 WeatherData[i].updated = false;
WiredHome 0:4435c965d95d 210 break;
WiredHome 0:4435c965d95d 211 case isInt:
WiredHome 0:4435c965d95d 212 WeatherData[i].value.iValue = 0;
WiredHome 0:4435c965d95d 213 WeatherData[i].updated = false;
WiredHome 0:4435c965d95d 214 break;
WiredHome 0:4435c965d95d 215 case isString:
WiredHome 0:4435c965d95d 216 if (WeatherData[i].value.sValue) {
WiredHome 0:4435c965d95d 217 free(WeatherData[i].value.sValue);
WiredHome 0:4435c965d95d 218 WeatherData[i].value.sValue = NULL;
WiredHome 0:4435c965d95d 219 }
WiredHome 0:4435c965d95d 220 WeatherData[i].updated = false;
WiredHome 0:4435c965d95d 221 break;
WiredHome 0:4435c965d95d 222 default:
WiredHome 0:4435c965d95d 223 break;
WiredHome 0:4435c965d95d 224 }
WiredHome 0:4435c965d95d 225 }
WiredHome 0:4435c965d95d 226 }
WiredHome 0:4435c965d95d 227
WiredHome 0:4435c965d95d 228 void NWSWeather::PrintWeatherRecord(uint16_t i)
WiredHome 0:4435c965d95d 229 {
WiredHome 0:4435c965d95d 230 if (i < WeatherItemCount) {
WiredHome 0:4435c965d95d 231 switch(WeatherData[i].typeis) {
WiredHome 0:4435c965d95d 232 case isFloat:
WiredHome 0:4435c965d95d 233 printf("%23s = %f\r\n", WeatherData[i].name, WeatherData[i].value.fValue);
WiredHome 0:4435c965d95d 234 break;
WiredHome 0:4435c965d95d 235 case isInt:
WiredHome 0:4435c965d95d 236 printf("%23s = %d\r\n", WeatherData[i].name, WeatherData[i].value.iValue);
WiredHome 0:4435c965d95d 237 break;
WiredHome 0:4435c965d95d 238 case isString:
WiredHome 0:4435c965d95d 239 printf("%23s = %s\r\n", WeatherData[i].name, WeatherData[i].value.sValue);
WiredHome 0:4435c965d95d 240 break;
WiredHome 0:4435c965d95d 241 default:
WiredHome 0:4435c965d95d 242 break;
WiredHome 0:4435c965d95d 243 }
WiredHome 0:4435c965d95d 244 }
WiredHome 0:4435c965d95d 245 }
WiredHome 0:4435c965d95d 246
WiredHome 0:4435c965d95d 247 void NWSWeather::PrintAllWeatherRecords(void)
WiredHome 0:4435c965d95d 248 {
WiredHome 0:4435c965d95d 249 for (int i=0; i<WeatherItemCount; i++) {
WiredHome 0:4435c965d95d 250 PrintWeatherRecord(i);
WiredHome 0:4435c965d95d 251 }
WiredHome 0:4435c965d95d 252 }
WiredHome 0:4435c965d95d 253
WiredHome 1:e077d6502c94 254 NWSWeather::NWSReturnCode_T NWSWeather::ParseWeatherRecord(char * p)
WiredHome 0:4435c965d95d 255 {
WiredHome 0:4435c965d95d 256 // <tag_name>value</tag_name>
WiredHome 0:4435c965d95d 257 // p1 p2 p3
WiredHome 0:4435c965d95d 258 char *p1, *p2, *p3;
WiredHome 0:4435c965d95d 259 int i;
WiredHome 0:4435c965d95d 260 int count = WeatherItemCount;
WiredHome 0:4435c965d95d 261
WiredHome 0:4435c965d95d 262 //printf("::%s::\r\n", p);
WiredHome 0:4435c965d95d 263 p1 = strchr(p, '<');
WiredHome 0:4435c965d95d 264 if (p1++) {
WiredHome 0:4435c965d95d 265 p2 = strchr(p1+1, '>');
WiredHome 0:4435c965d95d 266 if (p2) {
WiredHome 0:4435c965d95d 267 p3 = strchr(p2+1, '<');
WiredHome 0:4435c965d95d 268 if (p3) {
WiredHome 0:4435c965d95d 269 *p2++ = '\0';
WiredHome 0:4435c965d95d 270 *p3 = '\0';
WiredHome 0:4435c965d95d 271 //printf("tag: %s, value: %s\r\n", p1, p2);
WiredHome 0:4435c965d95d 272 for (i=0; i<count; i++) {
WiredHome 0:4435c965d95d 273 if (strcmp(p1, WeatherData[i].name) == 0) {
WiredHome 0:4435c965d95d 274 switch(WeatherData[i].typeis) {
WiredHome 0:4435c965d95d 275 case isFloat:
WiredHome 0:4435c965d95d 276 WeatherData[i].value.fValue = atof(p2);
WiredHome 0:4435c965d95d 277 WeatherData[i].updated = true;
WiredHome 0:4435c965d95d 278 break;
WiredHome 0:4435c965d95d 279 case isInt:
WiredHome 0:4435c965d95d 280 WeatherData[i].value.iValue = atoi(p2);
WiredHome 0:4435c965d95d 281 WeatherData[i].updated = true;
WiredHome 0:4435c965d95d 282 break;
WiredHome 0:4435c965d95d 283 case isString:
WiredHome 0:4435c965d95d 284 if (WeatherData[i].value.sValue)
WiredHome 0:4435c965d95d 285 free(WeatherData[i].value.sValue);
WiredHome 0:4435c965d95d 286 WeatherData[i].value.sValue = (char *)malloc(strlen(p2)+1);
WiredHome 0:4435c965d95d 287 if (WeatherData[i].value.sValue) {
WiredHome 0:4435c965d95d 288 strcpy(WeatherData[i].value.sValue, p2);
WiredHome 0:4435c965d95d 289 WeatherData[i].updated = true;
WiredHome 0:4435c965d95d 290 }
WiredHome 0:4435c965d95d 291 break;
WiredHome 0:4435c965d95d 292 default:
WiredHome 0:4435c965d95d 293 return badparameter;
WiredHome 0:4435c965d95d 294 //break;
WiredHome 0:4435c965d95d 295 }
WiredHome 0:4435c965d95d 296 //PrintWeatherRecord(i);
WiredHome 0:4435c965d95d 297 return noerror;
WiredHome 0:4435c965d95d 298 }
WiredHome 0:4435c965d95d 299 }
WiredHome 0:4435c965d95d 300 }
WiredHome 0:4435c965d95d 301 }
WiredHome 0:4435c965d95d 302 }
WiredHome 0:4435c965d95d 303 return noparamfound;
WiredHome 0:4435c965d95d 304 }
WiredHome 0:4435c965d95d 305
WiredHome 0:4435c965d95d 306 void NWSWeather::ParseWeatherXML(char * message)
WiredHome 0:4435c965d95d 307 {
WiredHome 0:4435c965d95d 308 char * p = message;
WiredHome 0:4435c965d95d 309
WiredHome 0:4435c965d95d 310 ClearWeatherRecords();
WiredHome 0:4435c965d95d 311 while (*p) {
WiredHome 0:4435c965d95d 312 char * n = strchr(p, '\n');
WiredHome 0:4435c965d95d 313 if (*n) {
WiredHome 0:4435c965d95d 314 *n = '\0';
WiredHome 0:4435c965d95d 315 ParseWeatherRecord(p);
WiredHome 0:4435c965d95d 316 p = n + 1;
WiredHome 0:4435c965d95d 317 } else {
WiredHome 0:4435c965d95d 318 ParseWeatherRecord(p);
WiredHome 0:4435c965d95d 319 break;
WiredHome 0:4435c965d95d 320 }
WiredHome 0:4435c965d95d 321 }
WiredHome 0:4435c965d95d 322 }