David Smart / NWSWeather
Committer:
WiredHome
Date:
Sun Nov 13 02:08:54 2016 +0000
Revision:
16:dd56cf216433
Parent:
15:c353545f9f13
Child:
17:99f09cc697fb
disable private memory manager

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 12:d70de07ca914 4 // attention: This program is copyright (c) 2014 - 2015 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 16:dd56cf216433 19 //#include "Utility.h" // private memory manager
WiredHome 13:a9ac9dde4f7f 20 #ifndef UTILITY_H
WiredHome 13:a9ac9dde4f7f 21 #define swMalloc malloc // use the standard
WiredHome 13:a9ac9dde4f7f 22 #define swFree free
WiredHome 13:a9ac9dde4f7f 23 #endif
WiredHome 13:a9ac9dde4f7f 24
WiredHome 15:c353545f9f13 25 //#define DEBUG "NWS "
WiredHome 2:eae60b64066e 26 // ...
WiredHome 2:eae60b64066e 27 // INFO("Stuff to show %d", var); // new-line is automatically appended
WiredHome 2:eae60b64066e 28 //
WiredHome 2:eae60b64066e 29 #if (defined(DEBUG) && !defined(TARGET_LPC11U24))
WiredHome 11:98afc5abbfb8 30 #define INFO(x, ...) std::printf("[INF %s %3d] " x "\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 11:98afc5abbfb8 31 #define WARN(x, ...) std::printf("[WRN %s %3d] " x "\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 11:98afc5abbfb8 32 #define ERR(x, ...) std::printf("[ERR %s %3d] " x "\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 2:eae60b64066e 33 #else
WiredHome 2:eae60b64066e 34 #define INFO(x, ...)
WiredHome 2:eae60b64066e 35 #define WARN(x, ...)
WiredHome 2:eae60b64066e 36 #define ERR(x, ...)
WiredHome 2:eae60b64066e 37 #endif
WiredHome 0:4435c965d95d 38
WiredHome 12:d70de07ca914 39 // 20151126 - Not sure when, but the NWS site stopped accepting requests unless a
WiredHome 12:d70de07ca914 40 // User-Agent was provided. It doesn't seem to matter the contents of
WiredHome 12:d70de07ca914 41 // the U-A string.
WiredHome 12:d70de07ca914 42 static const char * hdrs[] = {
WiredHome 12:d70de07ca914 43 "Connection", "keep-alive",
WiredHome 12:d70de07ca914 44 "Accept", "text/html",
WiredHome 12:d70de07ca914 45 "User-Agent", "SW_Client"
WiredHome 12:d70de07ca914 46 };
WiredHome 12:d70de07ca914 47 #define HDR_PAIRS 3
WiredHome 0:4435c965d95d 48
WiredHome 1:e077d6502c94 49 static NWSWeather::XMLItem_T WeatherData[] = {
WiredHome 1:e077d6502c94 50 {"observation_time_rfc822", NWSWeather::isString},
WiredHome 8:8a3371926b32 51 {"suggested_pickup", NWSWeather::isInt},
WiredHome 1:e077d6502c94 52 {"suggested_pickup_period", NWSWeather::isInt},
WiredHome 1:e077d6502c94 53 {"location", NWSWeather::isString},
WiredHome 1:e077d6502c94 54 {"weather", NWSWeather::isString},
WiredHome 1:e077d6502c94 55 {"temp_f", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 56 {"temp_c", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 57 {"relative_humidity", NWSWeather::isInt},
WiredHome 1:e077d6502c94 58 {"wind_degrees", NWSWeather::isInt},
WiredHome 1:e077d6502c94 59 {"wind_mph", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 60 {"pressure_mb", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 61 {"pressure_in", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 62 {"dewpoint_f", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 63 {"dewpoint_c", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 64 {"windchill_f", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 65 {"windchill_c", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 66 {"visibility_mi", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 67 {"icon_url_base", NWSWeather::isString},
WiredHome 1:e077d6502c94 68 {"icon_url_name", NWSWeather::isString},
WiredHome 1:e077d6502c94 69 {"latitude", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 70 {"longitude", NWSWeather::isFloat},
WiredHome 0:4435c965d95d 71 };
WiredHome 0:4435c965d95d 72
WiredHome 0:4435c965d95d 73 #define MAXPARAMLEN 23
WiredHome 0:4435c965d95d 74
WiredHome 0:4435c965d95d 75 #define WeatherItemCount (sizeof(WeatherData)/sizeof(WeatherData[0]))
WiredHome 0:4435c965d95d 76
WiredHome 13:a9ac9dde4f7f 77 NWSWeather::NWSWeather(const char * baseURL) : m_baseurl(0)
WiredHome 0:4435c965d95d 78 {
WiredHome 0:4435c965d95d 79 setAlternateURL(baseURL);
WiredHome 0:4435c965d95d 80 }
WiredHome 0:4435c965d95d 81
WiredHome 0:4435c965d95d 82 NWSWeather::~NWSWeather()
WiredHome 0:4435c965d95d 83 {
WiredHome 0:4435c965d95d 84 ClearWeatherRecords();
WiredHome 0:4435c965d95d 85 }
WiredHome 0:4435c965d95d 86
WiredHome 1:e077d6502c94 87 NWSWeather::NWSReturnCode_T NWSWeather::setAlternateURL(const char * baseURL)
WiredHome 0:4435c965d95d 88 {
WiredHome 11:98afc5abbfb8 89 int n = strlen(baseURL)+1;
WiredHome 11:98afc5abbfb8 90
WiredHome 0:4435c965d95d 91 if (m_baseurl)
WiredHome 13:a9ac9dde4f7f 92 swFree(m_baseurl);
WiredHome 13:a9ac9dde4f7f 93 m_baseurl = (char *)swMalloc(n);
WiredHome 0:4435c965d95d 94 if (m_baseurl)
WiredHome 11:98afc5abbfb8 95 strncpy(m_baseurl, baseURL, n);
WiredHome 0:4435c965d95d 96 else {
WiredHome 13:a9ac9dde4f7f 97 ERR("failed to swMalloc(%d)", n);
WiredHome 0:4435c965d95d 98 return nomemory;
WiredHome 0:4435c965d95d 99 }
WiredHome 0:4435c965d95d 100 ClearWeatherRecords();
WiredHome 0:4435c965d95d 101 return noerror;
WiredHome 0:4435c965d95d 102 }
WiredHome 0:4435c965d95d 103
WiredHome 0:4435c965d95d 104 uint16_t NWSWeather::count(void)
WiredHome 0:4435c965d95d 105 {
WiredHome 0:4435c965d95d 106 return WeatherItemCount;
WiredHome 0:4435c965d95d 107 }
WiredHome 0:4435c965d95d 108
WiredHome 1:e077d6502c94 109 NWSWeather::NWSReturnCode_T NWSWeather::get(const char * site, int responseSize)
WiredHome 0:4435c965d95d 110 {
WiredHome 6:cf96f2787a4e 111 HTTPClient http;
WiredHome 2:eae60b64066e 112 NWSReturnCode_T retCode = nomemory;
WiredHome 2:eae60b64066e 113 char *url = NULL;
WiredHome 13:a9ac9dde4f7f 114 char *message = (char *)swMalloc(responseSize);
WiredHome 12:d70de07ca914 115
WiredHome 2:eae60b64066e 116 INFO("get(%s)", site);
WiredHome 2:eae60b64066e 117 if (!message)
WiredHome 13:a9ac9dde4f7f 118 ERR("failed to swMalloc(%d)", responseSize);
WiredHome 2:eae60b64066e 119 while (message) {
WiredHome 11:98afc5abbfb8 120 int n = strlen(m_baseurl) + strlen(site) + 5;
WiredHome 11:98afc5abbfb8 121
WiredHome 13:a9ac9dde4f7f 122 url = (char *)swMalloc(n);
WiredHome 0:4435c965d95d 123 if (url) {
WiredHome 0:4435c965d95d 124 strcpy(url, m_baseurl);
WiredHome 0:4435c965d95d 125 strcat(url, site);
WiredHome 0:4435c965d95d 126 strcat(url, ".xml");
WiredHome 2:eae60b64066e 127 INFO(" url: %s", url);
WiredHome 0:4435c965d95d 128 http.setMaxRedirections(3);
WiredHome 12:d70de07ca914 129 http.customHeaders(hdrs, HDR_PAIRS);
WiredHome 0:4435c965d95d 130 int ret = http.get(url, message, responseSize);
WiredHome 0:4435c965d95d 131 if (!ret) {
WiredHome 2:eae60b64066e 132 INFO("ret is %d", ret);
WiredHome 0:4435c965d95d 133 if (http.getHTTPResponseCode() >= 300 && http.getHTTPResponseCode() < 400) {
WiredHome 14:bcc80874e824 134 INFO(" http.getHTTPResponseCode(): %d", http.getHTTPResponseCode());
WiredHome 2:eae60b64066e 135 retCode = noerror; // redirection that was not satisfied.
WiredHome 2:eae60b64066e 136 break;
WiredHome 0:4435c965d95d 137 } else {
WiredHome 6:cf96f2787a4e 138 INFO("wx get %d bytes.\r\n", strlen(message));
WiredHome 0:4435c965d95d 139 ParseWeatherXML(message);
WiredHome 11:98afc5abbfb8 140 INFO("wx parse complete.\r\n");
WiredHome 2:eae60b64066e 141 retCode = noerror;
WiredHome 2:eae60b64066e 142 break;
WiredHome 0:4435c965d95d 143 }
WiredHome 0:4435c965d95d 144 } else {
WiredHome 2:eae60b64066e 145 WARN("get returned %d, no response?", ret);
WiredHome 2:eae60b64066e 146 retCode = noresponse;
WiredHome 2:eae60b64066e 147 break;
WiredHome 0:4435c965d95d 148 }
WiredHome 0:4435c965d95d 149 } else {
WiredHome 13:a9ac9dde4f7f 150 ERR("failed to swMalloc(%d)", n);
WiredHome 2:eae60b64066e 151 retCode = nomemory;
WiredHome 2:eae60b64066e 152 break;
WiredHome 2:eae60b64066e 153 }
WiredHome 2:eae60b64066e 154 } // while(...) but configured with break for only 1 pass.
WiredHome 2:eae60b64066e 155 INFO(" ret is %d", retCode);
WiredHome 2:eae60b64066e 156 if (url)
WiredHome 13:a9ac9dde4f7f 157 swFree(url);
WiredHome 2:eae60b64066e 158 if (message)
WiredHome 13:a9ac9dde4f7f 159 swFree(message);
WiredHome 2:eae60b64066e 160 INFO(" mem freed.");
WiredHome 2:eae60b64066e 161 return retCode;
WiredHome 2:eae60b64066e 162 }
WiredHome 2:eae60b64066e 163
WiredHome 2:eae60b64066e 164
WiredHome 2:eae60b64066e 165 NWSWeather::NWSReturnCode_T NWSWeather::isUpdated(uint16_t i)
WiredHome 2:eae60b64066e 166 {
WiredHome 2:eae60b64066e 167 if (i < WeatherItemCount) {
WiredHome 2:eae60b64066e 168 if (WeatherData[i].updated)
WiredHome 2:eae60b64066e 169 return noerror;
WiredHome 2:eae60b64066e 170 else
WiredHome 2:eae60b64066e 171 return noupdate;
WiredHome 2:eae60b64066e 172 } else {
WiredHome 2:eae60b64066e 173 return badparameter;
WiredHome 2:eae60b64066e 174 }
WiredHome 2:eae60b64066e 175 }
WiredHome 2:eae60b64066e 176
WiredHome 2:eae60b64066e 177
WiredHome 2:eae60b64066e 178 NWSWeather::NWSReturnCode_T NWSWeather::isUpdated(const char * name)
WiredHome 2:eae60b64066e 179 {
WiredHome 2:eae60b64066e 180 if (name) {
WiredHome 2:eae60b64066e 181 for (int i=0; i < WeatherItemCount; i++) {
WiredHome 2:eae60b64066e 182 if (strcmp(name, WeatherData[i].name) == 0) {
WiredHome 2:eae60b64066e 183 if (WeatherData[i].updated)
WiredHome 2:eae60b64066e 184 return noerror;
WiredHome 2:eae60b64066e 185 else
WiredHome 2:eae60b64066e 186 return noupdate;
WiredHome 2:eae60b64066e 187 }
WiredHome 0:4435c965d95d 188 }
WiredHome 0:4435c965d95d 189 }
WiredHome 2:eae60b64066e 190 return badparameter;
WiredHome 0:4435c965d95d 191 }
WiredHome 0:4435c965d95d 192
WiredHome 0:4435c965d95d 193
WiredHome 1:e077d6502c94 194 NWSWeather::NWSReturnCode_T NWSWeather::getParam(uint16_t i, char *name, Value_T *value, TypeOf_T *typeis)
WiredHome 0:4435c965d95d 195 {
WiredHome 0:4435c965d95d 196 if (i < WeatherItemCount) {
WiredHome 0:4435c965d95d 197 *name = *WeatherData[i].name;
WiredHome 0:4435c965d95d 198 *value = WeatherData[i].value;
WiredHome 0:4435c965d95d 199 if (typeis)
WiredHome 0:4435c965d95d 200 *typeis = WeatherData[i].typeis;
WiredHome 0:4435c965d95d 201 return noerror;
WiredHome 0:4435c965d95d 202 } else {
WiredHome 0:4435c965d95d 203 return badparameter;
WiredHome 0:4435c965d95d 204 }
WiredHome 0:4435c965d95d 205 }
WiredHome 0:4435c965d95d 206
WiredHome 0:4435c965d95d 207
WiredHome 1:e077d6502c94 208 NWSWeather::NWSReturnCode_T NWSWeather::getParam(const char *name, Value_T *value, TypeOf_T *typeis)
WiredHome 0:4435c965d95d 209 {
WiredHome 2:eae60b64066e 210 for (int i=0; i < WeatherItemCount; i++) {
WiredHome 2:eae60b64066e 211 if (strcmp(name, WeatherData[i].name) == 0) {
WiredHome 2:eae60b64066e 212 *value = WeatherData[i].value;
WiredHome 2:eae60b64066e 213 if (typeis)
WiredHome 2:eae60b64066e 214 *typeis = WeatherData[i].typeis;
WiredHome 2:eae60b64066e 215 return noerror;
WiredHome 0:4435c965d95d 216 }
WiredHome 0:4435c965d95d 217 }
WiredHome 0:4435c965d95d 218 return badparameter;
WiredHome 0:4435c965d95d 219 }
WiredHome 0:4435c965d95d 220
WiredHome 0:4435c965d95d 221
WiredHome 0:4435c965d95d 222 void NWSWeather::ClearWeatherRecords(void)
WiredHome 0:4435c965d95d 223 {
WiredHome 0:4435c965d95d 224 int i;
WiredHome 0:4435c965d95d 225 int count = WeatherItemCount;
WiredHome 0:4435c965d95d 226
WiredHome 0:4435c965d95d 227 for (i=0; i<count; i++) {
WiredHome 0:4435c965d95d 228 switch(WeatherData[i].typeis) {
WiredHome 0:4435c965d95d 229 case isFloat:
WiredHome 0:4435c965d95d 230 WeatherData[i].value.fValue = 0.0;
WiredHome 0:4435c965d95d 231 WeatherData[i].updated = false;
WiredHome 0:4435c965d95d 232 break;
WiredHome 0:4435c965d95d 233 case isInt:
WiredHome 0:4435c965d95d 234 WeatherData[i].value.iValue = 0;
WiredHome 0:4435c965d95d 235 WeatherData[i].updated = false;
WiredHome 0:4435c965d95d 236 break;
WiredHome 0:4435c965d95d 237 case isString:
WiredHome 0:4435c965d95d 238 if (WeatherData[i].value.sValue) {
WiredHome 13:a9ac9dde4f7f 239 swFree(WeatherData[i].value.sValue);
WiredHome 0:4435c965d95d 240 WeatherData[i].value.sValue = NULL;
WiredHome 0:4435c965d95d 241 }
WiredHome 0:4435c965d95d 242 WeatherData[i].updated = false;
WiredHome 0:4435c965d95d 243 break;
WiredHome 0:4435c965d95d 244 default:
WiredHome 0:4435c965d95d 245 break;
WiredHome 0:4435c965d95d 246 }
WiredHome 0:4435c965d95d 247 }
WiredHome 0:4435c965d95d 248 }
WiredHome 0:4435c965d95d 249
WiredHome 0:4435c965d95d 250 void NWSWeather::PrintWeatherRecord(uint16_t i)
WiredHome 0:4435c965d95d 251 {
WiredHome 0:4435c965d95d 252 if (i < WeatherItemCount) {
WiredHome 0:4435c965d95d 253 switch(WeatherData[i].typeis) {
WiredHome 0:4435c965d95d 254 case isFloat:
WiredHome 0:4435c965d95d 255 printf("%23s = %f\r\n", WeatherData[i].name, WeatherData[i].value.fValue);
WiredHome 0:4435c965d95d 256 break;
WiredHome 0:4435c965d95d 257 case isInt:
WiredHome 0:4435c965d95d 258 printf("%23s = %d\r\n", WeatherData[i].name, WeatherData[i].value.iValue);
WiredHome 0:4435c965d95d 259 break;
WiredHome 0:4435c965d95d 260 case isString:
WiredHome 0:4435c965d95d 261 printf("%23s = %s\r\n", WeatherData[i].name, WeatherData[i].value.sValue);
WiredHome 0:4435c965d95d 262 break;
WiredHome 0:4435c965d95d 263 default:
WiredHome 0:4435c965d95d 264 break;
WiredHome 0:4435c965d95d 265 }
WiredHome 0:4435c965d95d 266 }
WiredHome 0:4435c965d95d 267 }
WiredHome 0:4435c965d95d 268
WiredHome 0:4435c965d95d 269 void NWSWeather::PrintAllWeatherRecords(void)
WiredHome 0:4435c965d95d 270 {
WiredHome 0:4435c965d95d 271 for (int i=0; i<WeatherItemCount; i++) {
WiredHome 0:4435c965d95d 272 PrintWeatherRecord(i);
WiredHome 0:4435c965d95d 273 }
WiredHome 0:4435c965d95d 274 }
WiredHome 0:4435c965d95d 275
WiredHome 1:e077d6502c94 276 NWSWeather::NWSReturnCode_T NWSWeather::ParseWeatherRecord(char * p)
WiredHome 0:4435c965d95d 277 {
WiredHome 0:4435c965d95d 278 // <tag_name>value</tag_name>
WiredHome 0:4435c965d95d 279 // p1 p2 p3
WiredHome 0:4435c965d95d 280 char *p1, *p2, *p3;
WiredHome 0:4435c965d95d 281 int i;
WiredHome 11:98afc5abbfb8 282 int n;
WiredHome 0:4435c965d95d 283 int count = WeatherItemCount;
WiredHome 0:4435c965d95d 284
WiredHome 11:98afc5abbfb8 285 INFO("ParseWeatherRecord(%s)", p);
WiredHome 11:98afc5abbfb8 286 p1 = strchr(p, '<'); // Pattern Matching <key>value</key>
WiredHome 0:4435c965d95d 287 if (p1++) {
WiredHome 0:4435c965d95d 288 p2 = strchr(p1+1, '>');
WiredHome 0:4435c965d95d 289 if (p2) {
WiredHome 0:4435c965d95d 290 p3 = strchr(p2+1, '<');
WiredHome 0:4435c965d95d 291 if (p3) {
WiredHome 0:4435c965d95d 292 *p2++ = '\0';
WiredHome 0:4435c965d95d 293 *p3 = '\0';
WiredHome 0:4435c965d95d 294 for (i=0; i<count; i++) {
WiredHome 0:4435c965d95d 295 if (strcmp(p1, WeatherData[i].name) == 0) {
WiredHome 0:4435c965d95d 296 switch(WeatherData[i].typeis) {
WiredHome 0:4435c965d95d 297 case isFloat:
WiredHome 0:4435c965d95d 298 WeatherData[i].value.fValue = atof(p2);
WiredHome 0:4435c965d95d 299 WeatherData[i].updated = true;
WiredHome 0:4435c965d95d 300 break;
WiredHome 0:4435c965d95d 301 case isInt:
WiredHome 0:4435c965d95d 302 WeatherData[i].value.iValue = atoi(p2);
WiredHome 0:4435c965d95d 303 WeatherData[i].updated = true;
WiredHome 0:4435c965d95d 304 break;
WiredHome 0:4435c965d95d 305 case isString:
WiredHome 0:4435c965d95d 306 if (WeatherData[i].value.sValue)
WiredHome 13:a9ac9dde4f7f 307 swFree(WeatherData[i].value.sValue);
WiredHome 11:98afc5abbfb8 308 n = strlen(p2)+1;
WiredHome 14:bcc80874e824 309 INFO(" pre- swMalloc(%d)", n);
WiredHome 13:a9ac9dde4f7f 310 WeatherData[i].value.sValue = (char *)swMalloc(n);
WiredHome 13:a9ac9dde4f7f 311 INFO(" post-swMalloc");
WiredHome 0:4435c965d95d 312 if (WeatherData[i].value.sValue) {
WiredHome 0:4435c965d95d 313 strcpy(WeatherData[i].value.sValue, p2);
WiredHome 0:4435c965d95d 314 WeatherData[i].updated = true;
WiredHome 11:98afc5abbfb8 315 } else {
WiredHome 13:a9ac9dde4f7f 316 ERR("failed to swMalloc(%d)", n);
WiredHome 11:98afc5abbfb8 317 break;
WiredHome 0:4435c965d95d 318 }
WiredHome 0:4435c965d95d 319 break;
WiredHome 0:4435c965d95d 320 default:
WiredHome 11:98afc5abbfb8 321 ERR("unknown type");
WiredHome 0:4435c965d95d 322 return badparameter;
WiredHome 0:4435c965d95d 323 //break;
WiredHome 0:4435c965d95d 324 }
WiredHome 14:bcc80874e824 325 //INFO("pw end");
WiredHome 0:4435c965d95d 326 return noerror;
WiredHome 0:4435c965d95d 327 }
WiredHome 0:4435c965d95d 328 }
WiredHome 0:4435c965d95d 329 }
WiredHome 0:4435c965d95d 330 }
WiredHome 0:4435c965d95d 331 }
WiredHome 14:bcc80874e824 332 //INFO("pw end");
WiredHome 0:4435c965d95d 333 return noparamfound;
WiredHome 0:4435c965d95d 334 }
WiredHome 0:4435c965d95d 335
WiredHome 0:4435c965d95d 336 void NWSWeather::ParseWeatherXML(char * message)
WiredHome 0:4435c965d95d 337 {
WiredHome 0:4435c965d95d 338 char * p = message;
WiredHome 0:4435c965d95d 339
WiredHome 11:98afc5abbfb8 340 INFO("ParseWeatherXML: %s", p);
WiredHome 0:4435c965d95d 341 ClearWeatherRecords();
WiredHome 11:98afc5abbfb8 342 INFO("cleared old");
WiredHome 0:4435c965d95d 343 while (*p) {
WiredHome 0:4435c965d95d 344 char * n = strchr(p, '\n');
WiredHome 0:4435c965d95d 345 if (*n) {
WiredHome 0:4435c965d95d 346 *n = '\0';
WiredHome 0:4435c965d95d 347 ParseWeatherRecord(p);
WiredHome 0:4435c965d95d 348 p = n + 1;
WiredHome 0:4435c965d95d 349 } else {
WiredHome 0:4435c965d95d 350 ParseWeatherRecord(p);
WiredHome 0:4435c965d95d 351 break;
WiredHome 0:4435c965d95d 352 }
WiredHome 0:4435c965d95d 353 }
WiredHome 0:4435c965d95d 354 }