A class to gather weather data from an NWS server.

Committer:
WiredHome
Date:
Sat Feb 23 18:01:39 2019 +0000
Revision:
20:29257dc4c7aa
Parent:
19:00af774c9b72
Modify return code on failure to indicate the cause.

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 19:00af774c9b72 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 0:4435c965d95d 49
WiredHome 18:699590fd8856 50 NWSWeather::NWSWeather(XMLItem_T * pList, int count) : m_baseurl(0)
WiredHome 0:4435c965d95d 51 {
WiredHome 18:699590fd8856 52 WeatherData = pList;
WiredHome 18:699590fd8856 53 WeatherItemCount = count;
WiredHome 18:699590fd8856 54 setAlternateURL(DEF_URL);
WiredHome 0:4435c965d95d 55 }
WiredHome 0:4435c965d95d 56
WiredHome 0:4435c965d95d 57 NWSWeather::~NWSWeather()
WiredHome 0:4435c965d95d 58 {
WiredHome 0:4435c965d95d 59 ClearWeatherRecords();
WiredHome 0:4435c965d95d 60 }
WiredHome 0:4435c965d95d 61
WiredHome 1:e077d6502c94 62 NWSWeather::NWSReturnCode_T NWSWeather::setAlternateURL(const char * baseURL)
WiredHome 0:4435c965d95d 63 {
WiredHome 11:98afc5abbfb8 64 int n = strlen(baseURL)+1;
WiredHome 11:98afc5abbfb8 65
WiredHome 0:4435c965d95d 66 if (m_baseurl)
WiredHome 13:a9ac9dde4f7f 67 swFree(m_baseurl);
WiredHome 13:a9ac9dde4f7f 68 m_baseurl = (char *)swMalloc(n);
WiredHome 0:4435c965d95d 69 if (m_baseurl)
WiredHome 11:98afc5abbfb8 70 strncpy(m_baseurl, baseURL, n);
WiredHome 0:4435c965d95d 71 else {
WiredHome 13:a9ac9dde4f7f 72 ERR("failed to swMalloc(%d)", n);
WiredHome 0:4435c965d95d 73 return nomemory;
WiredHome 0:4435c965d95d 74 }
WiredHome 0:4435c965d95d 75 ClearWeatherRecords();
WiredHome 0:4435c965d95d 76 return noerror;
WiredHome 0:4435c965d95d 77 }
WiredHome 0:4435c965d95d 78
WiredHome 0:4435c965d95d 79 uint16_t NWSWeather::count(void)
WiredHome 0:4435c965d95d 80 {
WiredHome 0:4435c965d95d 81 return WeatherItemCount;
WiredHome 0:4435c965d95d 82 }
WiredHome 0:4435c965d95d 83
WiredHome 17:99f09cc697fb 84 #if WEATHER_GOV == 1
WiredHome 1:e077d6502c94 85 NWSWeather::NWSReturnCode_T NWSWeather::get(const char * site, int responseSize)
WiredHome 17:99f09cc697fb 86 #elif OPEN_WEATHER == 1
WiredHome 17:99f09cc697fb 87 NWSWeather::NWSReturnCode_T NWSWeather::get(const char * site, const char * userid, int responseSize)
WiredHome 17:99f09cc697fb 88 #endif
WiredHome 0:4435c965d95d 89 {
WiredHome 6:cf96f2787a4e 90 HTTPClient http;
WiredHome 2:eae60b64066e 91 NWSReturnCode_T retCode = nomemory;
WiredHome 2:eae60b64066e 92 char *url = NULL;
WiredHome 13:a9ac9dde4f7f 93 char *message = (char *)swMalloc(responseSize);
WiredHome 12:d70de07ca914 94
WiredHome 2:eae60b64066e 95 INFO("get(%s)", site);
WiredHome 2:eae60b64066e 96 if (!message)
WiredHome 13:a9ac9dde4f7f 97 ERR("failed to swMalloc(%d)", responseSize);
WiredHome 2:eae60b64066e 98 while (message) {
WiredHome 17:99f09cc697fb 99 #if WEATHER_GOV == 1
WiredHome 17:99f09cc697fb 100 //https://www.weather.gov/data/current_obs/<loc_code>.xml
WiredHome 17:99f09cc697fb 101 // ++++
WiredHome 11:98afc5abbfb8 102 int n = strlen(m_baseurl) + strlen(site) + 5;
WiredHome 17:99f09cc697fb 103 #elif OPEN_WEATHER == 1
WiredHome 17:99f09cc697fb 104 //http://api.openweathermap.org/data/2.5/weather?mode=xml&units=imperial&id=<loc_code>&APPID=<user_id>
WiredHome 17:99f09cc697fb 105 // ++++ +++++++
WiredHome 17:99f09cc697fb 106 int n = strlen(m_baseurl) + 4 + strlen(site) + 7 + strlen(userid) + 1;
WiredHome 17:99f09cc697fb 107 #endif
WiredHome 13:a9ac9dde4f7f 108 url = (char *)swMalloc(n);
WiredHome 0:4435c965d95d 109 if (url) {
WiredHome 17:99f09cc697fb 110 #if WEATHER_GOV == 1
WiredHome 17:99f09cc697fb 111 sprintf(url, "%s%s%s.xml", m_baseurl, site);
WiredHome 17:99f09cc697fb 112 #elif OPEN_WEATHER == 1
WiredHome 17:99f09cc697fb 113 sprintf(url, "%s&id=%s&APPID=%s", m_baseurl, site, userid);
WiredHome 17:99f09cc697fb 114 #endif
WiredHome 2:eae60b64066e 115 INFO(" url: %s", url);
WiredHome 0:4435c965d95d 116 http.setMaxRedirections(3);
WiredHome 12:d70de07ca914 117 http.customHeaders(hdrs, HDR_PAIRS);
WiredHome 0:4435c965d95d 118 int ret = http.get(url, message, responseSize);
WiredHome 0:4435c965d95d 119 if (!ret) {
WiredHome 2:eae60b64066e 120 INFO("ret is %d", ret);
WiredHome 0:4435c965d95d 121 if (http.getHTTPResponseCode() >= 300 && http.getHTTPResponseCode() < 400) {
WiredHome 14:bcc80874e824 122 INFO(" http.getHTTPResponseCode(): %d", http.getHTTPResponseCode());
WiredHome 2:eae60b64066e 123 retCode = noerror; // redirection that was not satisfied.
WiredHome 2:eae60b64066e 124 break;
WiredHome 0:4435c965d95d 125 } else {
WiredHome 6:cf96f2787a4e 126 INFO("wx get %d bytes.\r\n", strlen(message));
WiredHome 0:4435c965d95d 127 ParseWeatherXML(message);
WiredHome 11:98afc5abbfb8 128 INFO("wx parse complete.\r\n");
WiredHome 2:eae60b64066e 129 retCode = noerror;
WiredHome 2:eae60b64066e 130 break;
WiredHome 0:4435c965d95d 131 }
WiredHome 0:4435c965d95d 132 } else {
WiredHome 2:eae60b64066e 133 WARN("get returned %d, no response?", ret);
WiredHome 20:29257dc4c7aa 134 retCode = (NWSReturnCode_T)ret; // return code from get also indicates type of error // noresponse;
WiredHome 2:eae60b64066e 135 break;
WiredHome 0:4435c965d95d 136 }
WiredHome 0:4435c965d95d 137 } else {
WiredHome 13:a9ac9dde4f7f 138 ERR("failed to swMalloc(%d)", n);
WiredHome 2:eae60b64066e 139 retCode = nomemory;
WiredHome 2:eae60b64066e 140 break;
WiredHome 2:eae60b64066e 141 }
WiredHome 2:eae60b64066e 142 } // while(...) but configured with break for only 1 pass.
WiredHome 2:eae60b64066e 143 INFO(" ret is %d", retCode);
WiredHome 2:eae60b64066e 144 if (url)
WiredHome 13:a9ac9dde4f7f 145 swFree(url);
WiredHome 2:eae60b64066e 146 if (message)
WiredHome 13:a9ac9dde4f7f 147 swFree(message);
WiredHome 2:eae60b64066e 148 INFO(" mem freed.");
WiredHome 2:eae60b64066e 149 return retCode;
WiredHome 2:eae60b64066e 150 }
WiredHome 2:eae60b64066e 151
WiredHome 2:eae60b64066e 152
WiredHome 2:eae60b64066e 153 NWSWeather::NWSReturnCode_T NWSWeather::isUpdated(uint16_t i)
WiredHome 2:eae60b64066e 154 {
WiredHome 2:eae60b64066e 155 if (i < WeatherItemCount) {
WiredHome 2:eae60b64066e 156 if (WeatherData[i].updated)
WiredHome 2:eae60b64066e 157 return noerror;
WiredHome 2:eae60b64066e 158 else
WiredHome 2:eae60b64066e 159 return noupdate;
WiredHome 2:eae60b64066e 160 } else {
WiredHome 2:eae60b64066e 161 return badparameter;
WiredHome 2:eae60b64066e 162 }
WiredHome 2:eae60b64066e 163 }
WiredHome 2:eae60b64066e 164
WiredHome 2:eae60b64066e 165
WiredHome 2:eae60b64066e 166 NWSWeather::NWSReturnCode_T NWSWeather::isUpdated(const char * name)
WiredHome 2:eae60b64066e 167 {
WiredHome 2:eae60b64066e 168 if (name) {
WiredHome 2:eae60b64066e 169 for (int i=0; i < WeatherItemCount; i++) {
WiredHome 18:699590fd8856 170 if (strcmp(name, WeatherData[i].key) == 0) {
WiredHome 2:eae60b64066e 171 if (WeatherData[i].updated)
WiredHome 2:eae60b64066e 172 return noerror;
WiredHome 2:eae60b64066e 173 else
WiredHome 2:eae60b64066e 174 return noupdate;
WiredHome 2:eae60b64066e 175 }
WiredHome 0:4435c965d95d 176 }
WiredHome 0:4435c965d95d 177 }
WiredHome 2:eae60b64066e 178 return badparameter;
WiredHome 0:4435c965d95d 179 }
WiredHome 0:4435c965d95d 180
WiredHome 0:4435c965d95d 181
WiredHome 1:e077d6502c94 182 NWSWeather::NWSReturnCode_T NWSWeather::getParam(uint16_t i, char *name, Value_T *value, TypeOf_T *typeis)
WiredHome 0:4435c965d95d 183 {
WiredHome 0:4435c965d95d 184 if (i < WeatherItemCount) {
WiredHome 18:699590fd8856 185 *name = *WeatherData[i].key;
WiredHome 0:4435c965d95d 186 *value = WeatherData[i].value;
WiredHome 0:4435c965d95d 187 if (typeis)
WiredHome 0:4435c965d95d 188 *typeis = WeatherData[i].typeis;
WiredHome 0:4435c965d95d 189 return noerror;
WiredHome 0:4435c965d95d 190 } else {
WiredHome 0:4435c965d95d 191 return badparameter;
WiredHome 0:4435c965d95d 192 }
WiredHome 0:4435c965d95d 193 }
WiredHome 0:4435c965d95d 194
WiredHome 0:4435c965d95d 195
WiredHome 1:e077d6502c94 196 NWSWeather::NWSReturnCode_T NWSWeather::getParam(const char *name, Value_T *value, TypeOf_T *typeis)
WiredHome 0:4435c965d95d 197 {
WiredHome 18:699590fd8856 198 return getParam(name, NULL, value, typeis);
WiredHome 18:699590fd8856 199 }
WiredHome 18:699590fd8856 200
WiredHome 18:699590fd8856 201
WiredHome 18:699590fd8856 202 NWSWeather::NWSReturnCode_T NWSWeather::getParam(const char *name, const char * param, Value_T *value, TypeOf_T *typeis)
WiredHome 18:699590fd8856 203 {
WiredHome 2:eae60b64066e 204 for (int i=0; i < WeatherItemCount; i++) {
WiredHome 18:699590fd8856 205 if (strcmp(name, WeatherData[i].key) == 0) {
WiredHome 18:699590fd8856 206 if (param == NULL || strcmp(param, WeatherData[i].param) == 0) {
WiredHome 18:699590fd8856 207 *value = WeatherData[i].value;
WiredHome 18:699590fd8856 208 if (typeis)
WiredHome 18:699590fd8856 209 *typeis = WeatherData[i].typeis;
WiredHome 18:699590fd8856 210 return noerror;
WiredHome 18:699590fd8856 211 }
WiredHome 0:4435c965d95d 212 }
WiredHome 0:4435c965d95d 213 }
WiredHome 0:4435c965d95d 214 return badparameter;
WiredHome 0:4435c965d95d 215 }
WiredHome 0:4435c965d95d 216
WiredHome 0:4435c965d95d 217
WiredHome 0:4435c965d95d 218 void NWSWeather::ClearWeatherRecords(void)
WiredHome 0:4435c965d95d 219 {
WiredHome 0:4435c965d95d 220 int i;
WiredHome 0:4435c965d95d 221 int count = WeatherItemCount;
WiredHome 0:4435c965d95d 222
WiredHome 0:4435c965d95d 223 for (i=0; i<count; i++) {
WiredHome 0:4435c965d95d 224 switch(WeatherData[i].typeis) {
WiredHome 0:4435c965d95d 225 case isFloat:
WiredHome 0:4435c965d95d 226 WeatherData[i].value.fValue = 0.0;
WiredHome 0:4435c965d95d 227 WeatherData[i].updated = false;
WiredHome 0:4435c965d95d 228 break;
WiredHome 0:4435c965d95d 229 case isInt:
WiredHome 0:4435c965d95d 230 WeatherData[i].value.iValue = 0;
WiredHome 0:4435c965d95d 231 WeatherData[i].updated = false;
WiredHome 0:4435c965d95d 232 break;
WiredHome 0:4435c965d95d 233 case isString:
WiredHome 0:4435c965d95d 234 if (WeatherData[i].value.sValue) {
WiredHome 13:a9ac9dde4f7f 235 swFree(WeatherData[i].value.sValue);
WiredHome 0:4435c965d95d 236 WeatherData[i].value.sValue = NULL;
WiredHome 0:4435c965d95d 237 }
WiredHome 0:4435c965d95d 238 WeatherData[i].updated = false;
WiredHome 0:4435c965d95d 239 break;
WiredHome 0:4435c965d95d 240 default:
WiredHome 0:4435c965d95d 241 break;
WiredHome 0:4435c965d95d 242 }
WiredHome 0:4435c965d95d 243 }
WiredHome 0:4435c965d95d 244 }
WiredHome 0:4435c965d95d 245
WiredHome 0:4435c965d95d 246 void NWSWeather::PrintWeatherRecord(uint16_t i)
WiredHome 0:4435c965d95d 247 {
WiredHome 0:4435c965d95d 248 if (i < WeatherItemCount) {
WiredHome 18:699590fd8856 249 printf("%23s::%-10s = ", WeatherData[i].key, WeatherData[i].param);
WiredHome 0:4435c965d95d 250 switch(WeatherData[i].typeis) {
WiredHome 0:4435c965d95d 251 case isFloat:
WiredHome 18:699590fd8856 252 printf("%f", WeatherData[i].value.fValue);
WiredHome 0:4435c965d95d 253 break;
WiredHome 0:4435c965d95d 254 case isInt:
WiredHome 18:699590fd8856 255 printf("%d", WeatherData[i].value.iValue);
WiredHome 0:4435c965d95d 256 break;
WiredHome 0:4435c965d95d 257 case isString:
WiredHome 18:699590fd8856 258 printf("%s", WeatherData[i].value.sValue);
WiredHome 0:4435c965d95d 259 break;
WiredHome 0:4435c965d95d 260 default:
WiredHome 0:4435c965d95d 261 break;
WiredHome 0:4435c965d95d 262 }
WiredHome 18:699590fd8856 263 printf("\r\n");
WiredHome 0:4435c965d95d 264 }
WiredHome 0:4435c965d95d 265 }
WiredHome 0:4435c965d95d 266
WiredHome 0:4435c965d95d 267 void NWSWeather::PrintAllWeatherRecords(void)
WiredHome 0:4435c965d95d 268 {
WiredHome 0:4435c965d95d 269 for (int i=0; i<WeatherItemCount; i++) {
WiredHome 0:4435c965d95d 270 PrintWeatherRecord(i);
WiredHome 0:4435c965d95d 271 }
WiredHome 0:4435c965d95d 272 }
WiredHome 0:4435c965d95d 273
WiredHome 18:699590fd8856 274 NWSWeather::NWSReturnCode_T NWSWeather::ExtractParam(int i, char * pValue, char * pEnd) {
WiredHome 18:699590fd8856 275 int n;
WiredHome 18:699590fd8856 276
WiredHome 18:699590fd8856 277 INFO("ExtractParam(%d, ...)", i);
WiredHome 18:699590fd8856 278 switch(WeatherData[i].typeis) {
WiredHome 18:699590fd8856 279 case isFloat:
WiredHome 18:699590fd8856 280 WeatherData[i].value.fValue = (float)atof(pValue);
WiredHome 18:699590fd8856 281 WeatherData[i].updated = true;
WiredHome 18:699590fd8856 282 INFO("%f", WeatherData[i].value.fValue);
WiredHome 18:699590fd8856 283 break;
WiredHome 18:699590fd8856 284 case isInt:
WiredHome 18:699590fd8856 285 WeatherData[i].value.iValue = atoi(pValue);
WiredHome 18:699590fd8856 286 WeatherData[i].updated = true;
WiredHome 18:699590fd8856 287 INFO("%d", WeatherData[i].value.iValue);
WiredHome 18:699590fd8856 288 break;
WiredHome 18:699590fd8856 289 case isString:
WiredHome 18:699590fd8856 290 if (WeatherData[i].value.sValue)
WiredHome 18:699590fd8856 291 swFree(WeatherData[i].value.sValue);
WiredHome 18:699590fd8856 292 n = pEnd - pValue;
WiredHome 18:699590fd8856 293 WeatherData[i].value.sValue = (char *)swMalloc(n+1);
WiredHome 18:699590fd8856 294 if (WeatherData[i].value.sValue) {
WiredHome 18:699590fd8856 295 strncpy(WeatherData[i].value.sValue, pValue, n);
WiredHome 18:699590fd8856 296 WeatherData[i].value.sValue[n] = '\0';
WiredHome 18:699590fd8856 297 WeatherData[i].updated = true;
WiredHome 18:699590fd8856 298 INFO(" info '%s'", WeatherData[i].value.sValue);
WiredHome 18:699590fd8856 299 } else {
WiredHome 18:699590fd8856 300 ERR("failed to swMalloc(%d)", n);
WiredHome 18:699590fd8856 301 return nomemory;
WiredHome 18:699590fd8856 302 }
WiredHome 18:699590fd8856 303 break;
WiredHome 18:699590fd8856 304 default:
WiredHome 18:699590fd8856 305 ERR("unknown type");
WiredHome 18:699590fd8856 306 return badparameter;
WiredHome 18:699590fd8856 307 //break;
WiredHome 18:699590fd8856 308 }
WiredHome 18:699590fd8856 309 INFO("...");
WiredHome 18:699590fd8856 310 return noerror;
WiredHome 18:699590fd8856 311 }
WiredHome 18:699590fd8856 312
WiredHome 1:e077d6502c94 313 NWSWeather::NWSReturnCode_T NWSWeather::ParseWeatherRecord(char * p)
WiredHome 0:4435c965d95d 314 {
WiredHome 18:699590fd8856 315 #if 1
WiredHome 18:699590fd8856 316 // Pattern Matching <thekey dontcare="something" value="thevalue"/>
WiredHome 18:699590fd8856 317 // | | |------| | |
WiredHome 18:699590fd8856 318 // | | | | +pEnd
WiredHome 18:699590fd8856 319 // | +pKeyE +pVal +pValE
WiredHome 18:699590fd8856 320 // +pKey
WiredHome 18:699590fd8856 321 //
WiredHome 18:699590fd8856 322 // <thekey>theValue</thekey>
WiredHome 18:699590fd8856 323 // | || | |
WiredHome 18:699590fd8856 324 // | || | +pEnd
WiredHome 18:699590fd8856 325 // | |+pVal +pValE
WiredHome 18:699590fd8856 326 // | +pKeyE
WiredHome 18:699590fd8856 327 // +pKey
WiredHome 18:699590fd8856 328 //
WiredHome 18:699590fd8856 329 char *pKey, *pEnd;
WiredHome 18:699590fd8856 330 char *pVal = NULL;
WiredHome 18:699590fd8856 331 char *pValE = NULL;
WiredHome 18:699590fd8856 332
WiredHome 18:699590fd8856 333 p = strchr(p, '<');
WiredHome 18:699590fd8856 334 while (p) {
WiredHome 18:699590fd8856 335 //INFO("ParseWeatherRecord \n%s\n", p);
WiredHome 18:699590fd8856 336 p++; // Advance past the '<'
WiredHome 18:699590fd8856 337 for (int i=0; i<WeatherItemCount; i++) {
WiredHome 18:699590fd8856 338 //INFO("\n check %s::%s", WeatherData[i].key, WeatherData[i].param);
WiredHome 18:699590fd8856 339 pKey = strstr(p, WeatherData[i].key);
WiredHome 18:699590fd8856 340 if (pKey && pKey == p && *(pKey-1) == '<') {
WiredHome 18:699590fd8856 341 //INFO(" key %s", pKey);
WiredHome 18:699590fd8856 342 if (WeatherData[i].param && WeatherData[i].param[0]) {
WiredHome 18:699590fd8856 343 // <thekey dontcare="something" value="thevalue"/>
WiredHome 18:699590fd8856 344 pEnd = strchr(pKey, '/');
WiredHome 18:699590fd8856 345 if (pEnd) {
WiredHome 18:699590fd8856 346 pVal = strstr(pKey, WeatherData[i].param);
WiredHome 18:699590fd8856 347 if (pVal && pVal < pEnd) {
WiredHome 18:699590fd8856 348 pVal = strchr(pVal, '"');
WiredHome 18:699590fd8856 349 if (pVal) {
WiredHome 18:699590fd8856 350 pVal++;
WiredHome 18:699590fd8856 351 //INFO(" val %s", pVal);
WiredHome 18:699590fd8856 352 pValE = strchr(pVal, '"');
WiredHome 18:699590fd8856 353 ExtractParam(i, pVal, pValE);
WiredHome 18:699590fd8856 354 INFO("Key %s::%s", WeatherData[i].key, WeatherData[i].param);
WiredHome 18:699590fd8856 355 }
WiredHome 18:699590fd8856 356 }
WiredHome 18:699590fd8856 357 }
WiredHome 18:699590fd8856 358 } else {
WiredHome 18:699590fd8856 359 // <thekey>theValue</key>
WiredHome 18:699590fd8856 360 pVal = strchr(pKey, '>');
WiredHome 18:699590fd8856 361 if (pVal) {
WiredHome 18:699590fd8856 362 pVal++;
WiredHome 18:699590fd8856 363 pValE = strchr(pVal, '<');
WiredHome 18:699590fd8856 364 if (pValE && *(pValE+1) == '/') {
WiredHome 18:699590fd8856 365 ExtractParam(i, pVal, pValE);
WiredHome 18:699590fd8856 366 INFO("Key %s", WeatherData[i].key);
WiredHome 18:699590fd8856 367 }
WiredHome 18:699590fd8856 368 }
WiredHome 18:699590fd8856 369 }
WiredHome 18:699590fd8856 370 }
WiredHome 18:699590fd8856 371 }
WiredHome 18:699590fd8856 372 p = strchr(p, '<');
WiredHome 18:699590fd8856 373 }
WiredHome 18:699590fd8856 374 #else
WiredHome 0:4435c965d95d 375 // <tag_name>value</tag_name>
WiredHome 17:99f09cc697fb 376 // pKey pValue
WiredHome 17:99f09cc697fb 377 char *pKey, *pValue, *pX;
WiredHome 0:4435c965d95d 378 int i;
WiredHome 11:98afc5abbfb8 379 int n;
WiredHome 0:4435c965d95d 380 int count = WeatherItemCount;
WiredHome 17:99f09cc697fb 381 bool parseIt = false;
WiredHome 0:4435c965d95d 382
WiredHome 11:98afc5abbfb8 383 INFO("ParseWeatherRecord(%s)", p);
WiredHome 17:99f09cc697fb 384 #if WEATHER_GOV == 1
WiredHome 17:99f09cc697fb 385 // Pattern Matching <key>value</key>
WiredHome 17:99f09cc697fb 386 // | +pValue
WiredHome 17:99f09cc697fb 387 // +pKey
WiredHome 17:99f09cc697fb 388 pKey = strchr(p, '<');
WiredHome 17:99f09cc697fb 389 if (pKey++) {
WiredHome 17:99f09cc697fb 390 pValue = strchr(pKey+1, '>');
WiredHome 17:99f09cc697fb 391 if (pValue) {
WiredHome 17:99f09cc697fb 392 p2 = strchr(pValue+1, '<');
WiredHome 17:99f09cc697fb 393 if (p2) {
WiredHome 17:99f09cc697fb 394 *pValue++ = '\0';
WiredHome 17:99f09cc697fb 395 *p2 = '\0';
WiredHome 17:99f09cc697fb 396 parseIt = true;
WiredHome 17:99f09cc697fb 397 }
WiredHome 17:99f09cc697fb 398 }
WiredHome 17:99f09cc697fb 399 }
WiredHome 17:99f09cc697fb 400 #elif OPEN_WEATHER == 1
WiredHome 17:99f09cc697fb 401 pKey = strchr(p, '<');
WiredHome 17:99f09cc697fb 402 // Pattern Matching <key dontcare="something" value="thevalue" dontcare="something"/>
WiredHome 17:99f09cc697fb 403 // | +pValue
WiredHome 17:99f09cc697fb 404 // +pKey
WiredHome 17:99f09cc697fb 405 if (pKey++) {
WiredHome 17:99f09cc697fb 406 pValue = strchr(pKey+1, ' ');
WiredHome 17:99f09cc697fb 407 if (pValue) {
WiredHome 17:99f09cc697fb 408 *pValue++ = '\0';
WiredHome 17:99f09cc697fb 409 pValue = strstr(pValue, "value=\"");
WiredHome 17:99f09cc697fb 410 if (pValue) {
WiredHome 17:99f09cc697fb 411 pValue += 7;
WiredHome 17:99f09cc697fb 412 pX = strchr(pValue, '"');
WiredHome 17:99f09cc697fb 413 if (pX) {
WiredHome 17:99f09cc697fb 414 *pX = '\0';
WiredHome 17:99f09cc697fb 415 parseIt = true;
WiredHome 17:99f09cc697fb 416 }
WiredHome 17:99f09cc697fb 417 }
WiredHome 17:99f09cc697fb 418 }
WiredHome 17:99f09cc697fb 419 }
WiredHome 17:99f09cc697fb 420 #endif
WiredHome 17:99f09cc697fb 421 if (parseIt) {
WiredHome 17:99f09cc697fb 422 for (i=0; i<count; i++) {
WiredHome 18:699590fd8856 423 if (strcmp(pKey, WeatherData[i].key) == 0) {
WiredHome 17:99f09cc697fb 424 switch(WeatherData[i].typeis) {
WiredHome 17:99f09cc697fb 425 case isFloat:
WiredHome 17:99f09cc697fb 426 WeatherData[i].value.fValue = atof(pValue);
WiredHome 17:99f09cc697fb 427 WeatherData[i].updated = true;
WiredHome 17:99f09cc697fb 428 break;
WiredHome 17:99f09cc697fb 429 case isInt:
WiredHome 17:99f09cc697fb 430 WeatherData[i].value.iValue = atoi(pValue);
WiredHome 17:99f09cc697fb 431 WeatherData[i].updated = true;
WiredHome 17:99f09cc697fb 432 break;
WiredHome 17:99f09cc697fb 433 case isString:
WiredHome 17:99f09cc697fb 434 if (WeatherData[i].value.sValue)
WiredHome 17:99f09cc697fb 435 swFree(WeatherData[i].value.sValue);
WiredHome 17:99f09cc697fb 436 n = strlen(pValue)+1;
WiredHome 17:99f09cc697fb 437 INFO(" pre- swMalloc(%d)", n);
WiredHome 17:99f09cc697fb 438 WeatherData[i].value.sValue = (char *)swMalloc(n);
WiredHome 17:99f09cc697fb 439 INFO(" post-swMalloc");
WiredHome 17:99f09cc697fb 440 if (WeatherData[i].value.sValue) {
WiredHome 17:99f09cc697fb 441 strcpy(WeatherData[i].value.sValue, pValue);
WiredHome 17:99f09cc697fb 442 WeatherData[i].updated = true;
WiredHome 17:99f09cc697fb 443 } else {
WiredHome 17:99f09cc697fb 444 ERR("failed to swMalloc(%d)", n);
WiredHome 17:99f09cc697fb 445 break;
WiredHome 0:4435c965d95d 446 }
WiredHome 17:99f09cc697fb 447 break;
WiredHome 17:99f09cc697fb 448 default:
WiredHome 17:99f09cc697fb 449 ERR("unknown type");
WiredHome 17:99f09cc697fb 450 return badparameter;
WiredHome 17:99f09cc697fb 451 //break;
WiredHome 0:4435c965d95d 452 }
WiredHome 17:99f09cc697fb 453 return noerror;
WiredHome 0:4435c965d95d 454 }
WiredHome 0:4435c965d95d 455 }
WiredHome 0:4435c965d95d 456 }
WiredHome 18:699590fd8856 457 #endif
WiredHome 0:4435c965d95d 458 return noparamfound;
WiredHome 0:4435c965d95d 459 }
WiredHome 0:4435c965d95d 460
WiredHome 0:4435c965d95d 461 void NWSWeather::ParseWeatherXML(char * message)
WiredHome 0:4435c965d95d 462 {
WiredHome 18:699590fd8856 463 char * p = strchr(message, '<');
WiredHome 0:4435c965d95d 464
WiredHome 0:4435c965d95d 465 ClearWeatherRecords();
WiredHome 18:699590fd8856 466 ParseWeatherRecord(p);
WiredHome 0:4435c965d95d 467 }