David Smart / NWSWeather
Committer:
WiredHome
Date:
Wed Jan 09 12:39:06 2019 +0000
Revision:
17:99f09cc697fb
Parent:
16:dd56cf216433
Child:
18:699590fd8856
Added alternate support for OpenWeather, after Weather.gov went secure-only (https).

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 17:99f09cc697fb 4 // attention: This program is copyright (c) 2014 - 2019 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 17:99f09cc697fb 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 17:99f09cc697fb 49 #if WEATHER_GOV == 1
WiredHome 1:e077d6502c94 50 static NWSWeather::XMLItem_T WeatherData[] = {
WiredHome 17:99f09cc697fb 51 {"observation_time_rfc822", NWSWeather::isString}, //
WiredHome 8:8a3371926b32 52 {"suggested_pickup", NWSWeather::isInt},
WiredHome 1:e077d6502c94 53 {"suggested_pickup_period", NWSWeather::isInt},
WiredHome 17:99f09cc697fb 54 {"location", NWSWeather::isString}, //
WiredHome 17:99f09cc697fb 55 {"weather", NWSWeather::isString}, //
WiredHome 17:99f09cc697fb 56 {"temp_f", NWSWeather::isFloat}, //
WiredHome 1:e077d6502c94 57 {"temp_c", NWSWeather::isFloat},
WiredHome 17:99f09cc697fb 58 {"relative_humidity", NWSWeather::isInt}, //
WiredHome 17:99f09cc697fb 59 {"wind_degrees", NWSWeather::isInt}, //
WiredHome 17:99f09cc697fb 60 {"wind_mph", NWSWeather::isFloat}, //
WiredHome 17:99f09cc697fb 61 {"pressure_mb", NWSWeather::isFloat}, //
WiredHome 1:e077d6502c94 62 {"pressure_in", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 63 {"dewpoint_f", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 64 {"dewpoint_c", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 65 {"windchill_f", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 66 {"windchill_c", NWSWeather::isFloat},
WiredHome 17:99f09cc697fb 67 {"visibility_mi", NWSWeather::isFloat}, //
WiredHome 1:e077d6502c94 68 {"icon_url_base", NWSWeather::isString},
WiredHome 1:e077d6502c94 69 {"icon_url_name", NWSWeather::isString},
WiredHome 1:e077d6502c94 70 {"latitude", NWSWeather::isFloat},
WiredHome 1:e077d6502c94 71 {"longitude", NWSWeather::isFloat},
WiredHome 0:4435c965d95d 72 };
WiredHome 17:99f09cc697fb 73 #elif OPEN_WEATHER == 1
WiredHome 17:99f09cc697fb 74 static NWSWeather::XMLItem_T WeatherData[] = {
WiredHome 17:99f09cc697fb 75 {"lastupdate", NWSWeather::isString}, //<lastupdate value="2019-01-09T00:15:00"/>
WiredHome 17:99f09cc697fb 76 {"city", NWSWeather::isString}, //<city id="4880889" name="Waterloo">
WiredHome 17:99f09cc697fb 77 {"weather", NWSWeather::isString}, //<weather number="802" value="scattered clouds" icon="03n"/>
WiredHome 17:99f09cc697fb 78 {"temperature", NWSWeather::isFloat}, //<temperature value="27.3" min="21.2" max="32" unit="fahrenheit"/>
WiredHome 17:99f09cc697fb 79 {"humidity", NWSWeather::isInt}, //<humidity value="68" unit="%"/>
WiredHome 17:99f09cc697fb 80 {"direction", NWSWeather::isInt}, //<direction value="310" code="NW" name="Northwest"/>
WiredHome 17:99f09cc697fb 81 {"speed", NWSWeather::isFloat}, //<speed value="26.4" name="Storm"/>
WiredHome 17:99f09cc697fb 82 {"pressure", NWSWeather::isInt}, //<pressure value="1021" unit="hPa"/>
WiredHome 17:99f09cc697fb 83 {"visibility", NWSWeather::isInt}, //<visibility value="16093"/>
WiredHome 17:99f09cc697fb 84 {"sun*rise", NWSWeather::isString}, //<sun rise="2019-01-09T13:38:27" set="2019-01-09T22:54:45"/>
WiredHome 17:99f09cc697fb 85 {"sun*set", NWSWeather::isString}, //<sun rise="2019-01-09T13:38:27" set="2019-01-09T22:54:45"/>
WiredHome 17:99f09cc697fb 86 };
WiredHome 17:99f09cc697fb 87 //<current>
WiredHome 17:99f09cc697fb 88 //<coord lon="-92.34" lat="42.49"/>
WiredHome 17:99f09cc697fb 89 //<country>US</country>
WiredHome 17:99f09cc697fb 90 //</city>
WiredHome 17:99f09cc697fb 91 //<wind>
WiredHome 17:99f09cc697fb 92 //<gusts value="19"/>
WiredHome 17:99f09cc697fb 93 //</wind>
WiredHome 17:99f09cc697fb 94 //<clouds value="40" name="scattered clouds"/>
WiredHome 17:99f09cc697fb 95 //<precipitation mode="no"/>
WiredHome 17:99f09cc697fb 96 //</current>
WiredHome 17:99f09cc697fb 97 #endif
WiredHome 0:4435c965d95d 98
WiredHome 0:4435c965d95d 99 #define MAXPARAMLEN 23
WiredHome 0:4435c965d95d 100
WiredHome 0:4435c965d95d 101 #define WeatherItemCount (sizeof(WeatherData)/sizeof(WeatherData[0]))
WiredHome 0:4435c965d95d 102
WiredHome 13:a9ac9dde4f7f 103 NWSWeather::NWSWeather(const char * baseURL) : m_baseurl(0)
WiredHome 0:4435c965d95d 104 {
WiredHome 0:4435c965d95d 105 setAlternateURL(baseURL);
WiredHome 0:4435c965d95d 106 }
WiredHome 0:4435c965d95d 107
WiredHome 0:4435c965d95d 108 NWSWeather::~NWSWeather()
WiredHome 0:4435c965d95d 109 {
WiredHome 0:4435c965d95d 110 ClearWeatherRecords();
WiredHome 0:4435c965d95d 111 }
WiredHome 0:4435c965d95d 112
WiredHome 1:e077d6502c94 113 NWSWeather::NWSReturnCode_T NWSWeather::setAlternateURL(const char * baseURL)
WiredHome 0:4435c965d95d 114 {
WiredHome 11:98afc5abbfb8 115 int n = strlen(baseURL)+1;
WiredHome 11:98afc5abbfb8 116
WiredHome 0:4435c965d95d 117 if (m_baseurl)
WiredHome 13:a9ac9dde4f7f 118 swFree(m_baseurl);
WiredHome 13:a9ac9dde4f7f 119 m_baseurl = (char *)swMalloc(n);
WiredHome 0:4435c965d95d 120 if (m_baseurl)
WiredHome 11:98afc5abbfb8 121 strncpy(m_baseurl, baseURL, n);
WiredHome 0:4435c965d95d 122 else {
WiredHome 13:a9ac9dde4f7f 123 ERR("failed to swMalloc(%d)", n);
WiredHome 0:4435c965d95d 124 return nomemory;
WiredHome 0:4435c965d95d 125 }
WiredHome 0:4435c965d95d 126 ClearWeatherRecords();
WiredHome 0:4435c965d95d 127 return noerror;
WiredHome 0:4435c965d95d 128 }
WiredHome 0:4435c965d95d 129
WiredHome 0:4435c965d95d 130 uint16_t NWSWeather::count(void)
WiredHome 0:4435c965d95d 131 {
WiredHome 0:4435c965d95d 132 return WeatherItemCount;
WiredHome 0:4435c965d95d 133 }
WiredHome 0:4435c965d95d 134
WiredHome 17:99f09cc697fb 135 #if WEATHER_GOV == 1
WiredHome 1:e077d6502c94 136 NWSWeather::NWSReturnCode_T NWSWeather::get(const char * site, int responseSize)
WiredHome 17:99f09cc697fb 137 #elif OPEN_WEATHER == 1
WiredHome 17:99f09cc697fb 138 NWSWeather::NWSReturnCode_T NWSWeather::get(const char * site, const char * userid, int responseSize)
WiredHome 17:99f09cc697fb 139 #endif
WiredHome 0:4435c965d95d 140 {
WiredHome 6:cf96f2787a4e 141 HTTPClient http;
WiredHome 2:eae60b64066e 142 NWSReturnCode_T retCode = nomemory;
WiredHome 2:eae60b64066e 143 char *url = NULL;
WiredHome 13:a9ac9dde4f7f 144 char *message = (char *)swMalloc(responseSize);
WiredHome 12:d70de07ca914 145
WiredHome 2:eae60b64066e 146 INFO("get(%s)", site);
WiredHome 2:eae60b64066e 147 if (!message)
WiredHome 13:a9ac9dde4f7f 148 ERR("failed to swMalloc(%d)", responseSize);
WiredHome 2:eae60b64066e 149 while (message) {
WiredHome 17:99f09cc697fb 150 #if WEATHER_GOV == 1
WiredHome 17:99f09cc697fb 151 //https://www.weather.gov/data/current_obs/<loc_code>.xml
WiredHome 17:99f09cc697fb 152 // ++++
WiredHome 11:98afc5abbfb8 153 int n = strlen(m_baseurl) + strlen(site) + 5;
WiredHome 17:99f09cc697fb 154 #elif OPEN_WEATHER == 1
WiredHome 17:99f09cc697fb 155 //http://api.openweathermap.org/data/2.5/weather?mode=xml&units=imperial&id=<loc_code>&APPID=<user_id>
WiredHome 17:99f09cc697fb 156 // ++++ +++++++
WiredHome 17:99f09cc697fb 157 int n = strlen(m_baseurl) + 4 + strlen(site) + 7 + strlen(userid) + 1;
WiredHome 17:99f09cc697fb 158 #endif
WiredHome 13:a9ac9dde4f7f 159 url = (char *)swMalloc(n);
WiredHome 0:4435c965d95d 160 if (url) {
WiredHome 17:99f09cc697fb 161 #if WEATHER_GOV == 1
WiredHome 17:99f09cc697fb 162 //strcpy(url, m_baseurl);
WiredHome 17:99f09cc697fb 163 //strcat(url, site);
WiredHome 17:99f09cc697fb 164 //strcat(url, ".xml");
WiredHome 17:99f09cc697fb 165 sprintf(url, "%s%s%s.xml", m_baseurl, site);
WiredHome 17:99f09cc697fb 166 #elif OPEN_WEATHER == 1
WiredHome 17:99f09cc697fb 167 sprintf(url, "%s&id=%s&APPID=%s", m_baseurl, site, userid);
WiredHome 17:99f09cc697fb 168 #endif
WiredHome 2:eae60b64066e 169 INFO(" url: %s", url);
WiredHome 0:4435c965d95d 170 http.setMaxRedirections(3);
WiredHome 12:d70de07ca914 171 http.customHeaders(hdrs, HDR_PAIRS);
WiredHome 0:4435c965d95d 172 int ret = http.get(url, message, responseSize);
WiredHome 0:4435c965d95d 173 if (!ret) {
WiredHome 2:eae60b64066e 174 INFO("ret is %d", ret);
WiredHome 0:4435c965d95d 175 if (http.getHTTPResponseCode() >= 300 && http.getHTTPResponseCode() < 400) {
WiredHome 14:bcc80874e824 176 INFO(" http.getHTTPResponseCode(): %d", http.getHTTPResponseCode());
WiredHome 2:eae60b64066e 177 retCode = noerror; // redirection that was not satisfied.
WiredHome 2:eae60b64066e 178 break;
WiredHome 0:4435c965d95d 179 } else {
WiredHome 6:cf96f2787a4e 180 INFO("wx get %d bytes.\r\n", strlen(message));
WiredHome 0:4435c965d95d 181 ParseWeatherXML(message);
WiredHome 11:98afc5abbfb8 182 INFO("wx parse complete.\r\n");
WiredHome 2:eae60b64066e 183 retCode = noerror;
WiredHome 2:eae60b64066e 184 break;
WiredHome 0:4435c965d95d 185 }
WiredHome 0:4435c965d95d 186 } else {
WiredHome 2:eae60b64066e 187 WARN("get returned %d, no response?", ret);
WiredHome 2:eae60b64066e 188 retCode = noresponse;
WiredHome 2:eae60b64066e 189 break;
WiredHome 0:4435c965d95d 190 }
WiredHome 0:4435c965d95d 191 } else {
WiredHome 13:a9ac9dde4f7f 192 ERR("failed to swMalloc(%d)", n);
WiredHome 2:eae60b64066e 193 retCode = nomemory;
WiredHome 2:eae60b64066e 194 break;
WiredHome 2:eae60b64066e 195 }
WiredHome 2:eae60b64066e 196 } // while(...) but configured with break for only 1 pass.
WiredHome 2:eae60b64066e 197 INFO(" ret is %d", retCode);
WiredHome 2:eae60b64066e 198 if (url)
WiredHome 13:a9ac9dde4f7f 199 swFree(url);
WiredHome 2:eae60b64066e 200 if (message)
WiredHome 13:a9ac9dde4f7f 201 swFree(message);
WiredHome 2:eae60b64066e 202 INFO(" mem freed.");
WiredHome 2:eae60b64066e 203 return retCode;
WiredHome 2:eae60b64066e 204 }
WiredHome 2:eae60b64066e 205
WiredHome 2:eae60b64066e 206
WiredHome 2:eae60b64066e 207 NWSWeather::NWSReturnCode_T NWSWeather::isUpdated(uint16_t i)
WiredHome 2:eae60b64066e 208 {
WiredHome 2:eae60b64066e 209 if (i < WeatherItemCount) {
WiredHome 2:eae60b64066e 210 if (WeatherData[i].updated)
WiredHome 2:eae60b64066e 211 return noerror;
WiredHome 2:eae60b64066e 212 else
WiredHome 2:eae60b64066e 213 return noupdate;
WiredHome 2:eae60b64066e 214 } else {
WiredHome 2:eae60b64066e 215 return badparameter;
WiredHome 2:eae60b64066e 216 }
WiredHome 2:eae60b64066e 217 }
WiredHome 2:eae60b64066e 218
WiredHome 2:eae60b64066e 219
WiredHome 2:eae60b64066e 220 NWSWeather::NWSReturnCode_T NWSWeather::isUpdated(const char * name)
WiredHome 2:eae60b64066e 221 {
WiredHome 2:eae60b64066e 222 if (name) {
WiredHome 2:eae60b64066e 223 for (int i=0; i < WeatherItemCount; i++) {
WiredHome 2:eae60b64066e 224 if (strcmp(name, WeatherData[i].name) == 0) {
WiredHome 2:eae60b64066e 225 if (WeatherData[i].updated)
WiredHome 2:eae60b64066e 226 return noerror;
WiredHome 2:eae60b64066e 227 else
WiredHome 2:eae60b64066e 228 return noupdate;
WiredHome 2:eae60b64066e 229 }
WiredHome 0:4435c965d95d 230 }
WiredHome 0:4435c965d95d 231 }
WiredHome 2:eae60b64066e 232 return badparameter;
WiredHome 0:4435c965d95d 233 }
WiredHome 0:4435c965d95d 234
WiredHome 0:4435c965d95d 235
WiredHome 1:e077d6502c94 236 NWSWeather::NWSReturnCode_T NWSWeather::getParam(uint16_t i, char *name, Value_T *value, TypeOf_T *typeis)
WiredHome 0:4435c965d95d 237 {
WiredHome 0:4435c965d95d 238 if (i < WeatherItemCount) {
WiredHome 0:4435c965d95d 239 *name = *WeatherData[i].name;
WiredHome 0:4435c965d95d 240 *value = WeatherData[i].value;
WiredHome 0:4435c965d95d 241 if (typeis)
WiredHome 0:4435c965d95d 242 *typeis = WeatherData[i].typeis;
WiredHome 0:4435c965d95d 243 return noerror;
WiredHome 0:4435c965d95d 244 } else {
WiredHome 0:4435c965d95d 245 return badparameter;
WiredHome 0:4435c965d95d 246 }
WiredHome 0:4435c965d95d 247 }
WiredHome 0:4435c965d95d 248
WiredHome 0:4435c965d95d 249
WiredHome 1:e077d6502c94 250 NWSWeather::NWSReturnCode_T NWSWeather::getParam(const char *name, Value_T *value, TypeOf_T *typeis)
WiredHome 0:4435c965d95d 251 {
WiredHome 2:eae60b64066e 252 for (int i=0; i < WeatherItemCount; i++) {
WiredHome 2:eae60b64066e 253 if (strcmp(name, WeatherData[i].name) == 0) {
WiredHome 2:eae60b64066e 254 *value = WeatherData[i].value;
WiredHome 2:eae60b64066e 255 if (typeis)
WiredHome 2:eae60b64066e 256 *typeis = WeatherData[i].typeis;
WiredHome 2:eae60b64066e 257 return noerror;
WiredHome 0:4435c965d95d 258 }
WiredHome 0:4435c965d95d 259 }
WiredHome 0:4435c965d95d 260 return badparameter;
WiredHome 0:4435c965d95d 261 }
WiredHome 0:4435c965d95d 262
WiredHome 0:4435c965d95d 263
WiredHome 0:4435c965d95d 264 void NWSWeather::ClearWeatherRecords(void)
WiredHome 0:4435c965d95d 265 {
WiredHome 0:4435c965d95d 266 int i;
WiredHome 0:4435c965d95d 267 int count = WeatherItemCount;
WiredHome 0:4435c965d95d 268
WiredHome 0:4435c965d95d 269 for (i=0; i<count; i++) {
WiredHome 0:4435c965d95d 270 switch(WeatherData[i].typeis) {
WiredHome 0:4435c965d95d 271 case isFloat:
WiredHome 0:4435c965d95d 272 WeatherData[i].value.fValue = 0.0;
WiredHome 0:4435c965d95d 273 WeatherData[i].updated = false;
WiredHome 0:4435c965d95d 274 break;
WiredHome 0:4435c965d95d 275 case isInt:
WiredHome 0:4435c965d95d 276 WeatherData[i].value.iValue = 0;
WiredHome 0:4435c965d95d 277 WeatherData[i].updated = false;
WiredHome 0:4435c965d95d 278 break;
WiredHome 0:4435c965d95d 279 case isString:
WiredHome 0:4435c965d95d 280 if (WeatherData[i].value.sValue) {
WiredHome 13:a9ac9dde4f7f 281 swFree(WeatherData[i].value.sValue);
WiredHome 0:4435c965d95d 282 WeatherData[i].value.sValue = NULL;
WiredHome 0:4435c965d95d 283 }
WiredHome 0:4435c965d95d 284 WeatherData[i].updated = false;
WiredHome 0:4435c965d95d 285 break;
WiredHome 0:4435c965d95d 286 default:
WiredHome 0:4435c965d95d 287 break;
WiredHome 0:4435c965d95d 288 }
WiredHome 0:4435c965d95d 289 }
WiredHome 0:4435c965d95d 290 }
WiredHome 0:4435c965d95d 291
WiredHome 0:4435c965d95d 292 void NWSWeather::PrintWeatherRecord(uint16_t i)
WiredHome 0:4435c965d95d 293 {
WiredHome 0:4435c965d95d 294 if (i < WeatherItemCount) {
WiredHome 0:4435c965d95d 295 switch(WeatherData[i].typeis) {
WiredHome 0:4435c965d95d 296 case isFloat:
WiredHome 0:4435c965d95d 297 printf("%23s = %f\r\n", WeatherData[i].name, WeatherData[i].value.fValue);
WiredHome 0:4435c965d95d 298 break;
WiredHome 0:4435c965d95d 299 case isInt:
WiredHome 0:4435c965d95d 300 printf("%23s = %d\r\n", WeatherData[i].name, WeatherData[i].value.iValue);
WiredHome 0:4435c965d95d 301 break;
WiredHome 0:4435c965d95d 302 case isString:
WiredHome 0:4435c965d95d 303 printf("%23s = %s\r\n", WeatherData[i].name, WeatherData[i].value.sValue);
WiredHome 0:4435c965d95d 304 break;
WiredHome 0:4435c965d95d 305 default:
WiredHome 0:4435c965d95d 306 break;
WiredHome 0:4435c965d95d 307 }
WiredHome 0:4435c965d95d 308 }
WiredHome 0:4435c965d95d 309 }
WiredHome 0:4435c965d95d 310
WiredHome 0:4435c965d95d 311 void NWSWeather::PrintAllWeatherRecords(void)
WiredHome 0:4435c965d95d 312 {
WiredHome 0:4435c965d95d 313 for (int i=0; i<WeatherItemCount; i++) {
WiredHome 0:4435c965d95d 314 PrintWeatherRecord(i);
WiredHome 0:4435c965d95d 315 }
WiredHome 0:4435c965d95d 316 }
WiredHome 0:4435c965d95d 317
WiredHome 1:e077d6502c94 318 NWSWeather::NWSReturnCode_T NWSWeather::ParseWeatherRecord(char * p)
WiredHome 0:4435c965d95d 319 {
WiredHome 0:4435c965d95d 320 // <tag_name>value</tag_name>
WiredHome 17:99f09cc697fb 321 // pKey pValue
WiredHome 17:99f09cc697fb 322 char *pKey, *pValue, *pX;
WiredHome 0:4435c965d95d 323 int i;
WiredHome 11:98afc5abbfb8 324 int n;
WiredHome 0:4435c965d95d 325 int count = WeatherItemCount;
WiredHome 17:99f09cc697fb 326 bool parseIt = false;
WiredHome 0:4435c965d95d 327
WiredHome 11:98afc5abbfb8 328 INFO("ParseWeatherRecord(%s)", p);
WiredHome 17:99f09cc697fb 329 #if WEATHER_GOV == 1
WiredHome 17:99f09cc697fb 330 // Pattern Matching <key>value</key>
WiredHome 17:99f09cc697fb 331 // | +pValue
WiredHome 17:99f09cc697fb 332 // +pKey
WiredHome 17:99f09cc697fb 333 pKey = strchr(p, '<');
WiredHome 17:99f09cc697fb 334 if (pKey++) {
WiredHome 17:99f09cc697fb 335 pValue = strchr(pKey+1, '>');
WiredHome 17:99f09cc697fb 336 if (pValue) {
WiredHome 17:99f09cc697fb 337 p2 = strchr(pValue+1, '<');
WiredHome 17:99f09cc697fb 338 if (p2) {
WiredHome 17:99f09cc697fb 339 *pValue++ = '\0';
WiredHome 17:99f09cc697fb 340 *p2 = '\0';
WiredHome 17:99f09cc697fb 341 parseIt = true;
WiredHome 17:99f09cc697fb 342 }
WiredHome 17:99f09cc697fb 343 }
WiredHome 17:99f09cc697fb 344 }
WiredHome 17:99f09cc697fb 345 #elif OPEN_WEATHER == 1
WiredHome 17:99f09cc697fb 346 pKey = strchr(p, '<');
WiredHome 17:99f09cc697fb 347 // Pattern Matching <key dontcare="something" value="thevalue" dontcare="something"/>
WiredHome 17:99f09cc697fb 348 // | +pValue
WiredHome 17:99f09cc697fb 349 // +pKey
WiredHome 17:99f09cc697fb 350 if (pKey++) {
WiredHome 17:99f09cc697fb 351 pValue = strchr(pKey+1, ' ');
WiredHome 17:99f09cc697fb 352 if (pValue) {
WiredHome 17:99f09cc697fb 353 *pValue++ = '\0';
WiredHome 17:99f09cc697fb 354 pValue = strstr(pValue, "value=\"");
WiredHome 17:99f09cc697fb 355 if (pValue) {
WiredHome 17:99f09cc697fb 356 pValue += 7;
WiredHome 17:99f09cc697fb 357 pX = strchr(pValue, '"');
WiredHome 17:99f09cc697fb 358 if (pX) {
WiredHome 17:99f09cc697fb 359 *pX = '\0';
WiredHome 17:99f09cc697fb 360 parseIt = true;
WiredHome 17:99f09cc697fb 361 }
WiredHome 17:99f09cc697fb 362 }
WiredHome 17:99f09cc697fb 363 }
WiredHome 17:99f09cc697fb 364 }
WiredHome 17:99f09cc697fb 365 #endif
WiredHome 17:99f09cc697fb 366 if (parseIt) {
WiredHome 17:99f09cc697fb 367 for (i=0; i<count; i++) {
WiredHome 17:99f09cc697fb 368 if (strcmp(pKey, WeatherData[i].name) == 0) {
WiredHome 17:99f09cc697fb 369 switch(WeatherData[i].typeis) {
WiredHome 17:99f09cc697fb 370 case isFloat:
WiredHome 17:99f09cc697fb 371 WeatherData[i].value.fValue = atof(pValue);
WiredHome 17:99f09cc697fb 372 WeatherData[i].updated = true;
WiredHome 17:99f09cc697fb 373 break;
WiredHome 17:99f09cc697fb 374 case isInt:
WiredHome 17:99f09cc697fb 375 WeatherData[i].value.iValue = atoi(pValue);
WiredHome 17:99f09cc697fb 376 WeatherData[i].updated = true;
WiredHome 17:99f09cc697fb 377 break;
WiredHome 17:99f09cc697fb 378 case isString:
WiredHome 17:99f09cc697fb 379 if (WeatherData[i].value.sValue)
WiredHome 17:99f09cc697fb 380 swFree(WeatherData[i].value.sValue);
WiredHome 17:99f09cc697fb 381 n = strlen(pValue)+1;
WiredHome 17:99f09cc697fb 382 INFO(" pre- swMalloc(%d)", n);
WiredHome 17:99f09cc697fb 383 WeatherData[i].value.sValue = (char *)swMalloc(n);
WiredHome 17:99f09cc697fb 384 INFO(" post-swMalloc");
WiredHome 17:99f09cc697fb 385 if (WeatherData[i].value.sValue) {
WiredHome 17:99f09cc697fb 386 strcpy(WeatherData[i].value.sValue, pValue);
WiredHome 17:99f09cc697fb 387 WeatherData[i].updated = true;
WiredHome 17:99f09cc697fb 388 } else {
WiredHome 17:99f09cc697fb 389 ERR("failed to swMalloc(%d)", n);
WiredHome 17:99f09cc697fb 390 break;
WiredHome 0:4435c965d95d 391 }
WiredHome 17:99f09cc697fb 392 break;
WiredHome 17:99f09cc697fb 393 default:
WiredHome 17:99f09cc697fb 394 ERR("unknown type");
WiredHome 17:99f09cc697fb 395 return badparameter;
WiredHome 17:99f09cc697fb 396 //break;
WiredHome 0:4435c965d95d 397 }
WiredHome 17:99f09cc697fb 398 //INFO("pw end");
WiredHome 17:99f09cc697fb 399 return noerror;
WiredHome 0:4435c965d95d 400 }
WiredHome 0:4435c965d95d 401 }
WiredHome 0:4435c965d95d 402 }
WiredHome 14:bcc80874e824 403 //INFO("pw end");
WiredHome 0:4435c965d95d 404 return noparamfound;
WiredHome 0:4435c965d95d 405 }
WiredHome 0:4435c965d95d 406
WiredHome 0:4435c965d95d 407 void NWSWeather::ParseWeatherXML(char * message)
WiredHome 0:4435c965d95d 408 {
WiredHome 0:4435c965d95d 409 char * p = message;
WiredHome 0:4435c965d95d 410
WiredHome 11:98afc5abbfb8 411 INFO("ParseWeatherXML: %s", p);
WiredHome 0:4435c965d95d 412 ClearWeatherRecords();
WiredHome 11:98afc5abbfb8 413 INFO("cleared old");
WiredHome 0:4435c965d95d 414 while (*p) {
WiredHome 17:99f09cc697fb 415 char * n;
WiredHome 17:99f09cc697fb 416 #if WEATHER_GOV == 1
WiredHome 17:99f09cc697fb 417 n = strchr(p, '\n');
WiredHome 17:99f09cc697fb 418 #elif OPEN_WEATHER == 1
WiredHome 17:99f09cc697fb 419 n = strchr(p, '>');
WiredHome 17:99f09cc697fb 420 #endif
WiredHome 0:4435c965d95d 421 if (*n) {
WiredHome 0:4435c965d95d 422 *n = '\0';
WiredHome 0:4435c965d95d 423 ParseWeatherRecord(p);
WiredHome 0:4435c965d95d 424 p = n + 1;
WiredHome 0:4435c965d95d 425 } else {
WiredHome 0:4435c965d95d 426 ParseWeatherRecord(p);
WiredHome 0:4435c965d95d 427 break;
WiredHome 0:4435c965d95d 428 }
WiredHome 0:4435c965d95d 429 }
WiredHome 0:4435c965d95d 430 }