Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: NWSWeather.cpp
- Revision:
- 17:99f09cc697fb
- Parent:
- 16:dd56cf216433
- Child:
- 18:699590fd8856
diff -r dd56cf216433 -r 99f09cc697fb NWSWeather.cpp --- a/NWSWeather.cpp Sun Nov 13 02:08:54 2016 +0000 +++ b/NWSWeather.cpp Wed Jan 09 12:39:06 2019 +0000 @@ -1,7 +1,7 @@ // // This file contains the interface for gathering forecast from NWS. // -// attention: This program is copyright (c) 2014 - 2015 by Smartware Computing, all +// attention: This program is copyright (c) 2014 - 2019 by Smartware Computing, all // rights reserved. // // This software, and/or material is the property of Smartware Computing. All @@ -22,7 +22,7 @@ #define swFree free #endif -//#define DEBUG "NWS " +#define DEBUG "NWS " // ... // INFO("Stuff to show %d", var); // new-line is automatically appended // @@ -46,29 +46,55 @@ }; #define HDR_PAIRS 3 +#if WEATHER_GOV == 1 static NWSWeather::XMLItem_T WeatherData[] = { - {"observation_time_rfc822", NWSWeather::isString}, + {"observation_time_rfc822", NWSWeather::isString}, // {"suggested_pickup", NWSWeather::isInt}, {"suggested_pickup_period", NWSWeather::isInt}, - {"location", NWSWeather::isString}, - {"weather", NWSWeather::isString}, - {"temp_f", NWSWeather::isFloat}, + {"location", NWSWeather::isString}, // + {"weather", NWSWeather::isString}, // + {"temp_f", NWSWeather::isFloat}, // {"temp_c", NWSWeather::isFloat}, - {"relative_humidity", NWSWeather::isInt}, - {"wind_degrees", NWSWeather::isInt}, - {"wind_mph", NWSWeather::isFloat}, - {"pressure_mb", NWSWeather::isFloat}, + {"relative_humidity", NWSWeather::isInt}, // + {"wind_degrees", NWSWeather::isInt}, // + {"wind_mph", NWSWeather::isFloat}, // + {"pressure_mb", NWSWeather::isFloat}, // {"pressure_in", NWSWeather::isFloat}, {"dewpoint_f", NWSWeather::isFloat}, {"dewpoint_c", NWSWeather::isFloat}, {"windchill_f", NWSWeather::isFloat}, {"windchill_c", NWSWeather::isFloat}, - {"visibility_mi", NWSWeather::isFloat}, + {"visibility_mi", NWSWeather::isFloat}, // {"icon_url_base", NWSWeather::isString}, {"icon_url_name", NWSWeather::isString}, {"latitude", NWSWeather::isFloat}, {"longitude", NWSWeather::isFloat}, }; +#elif OPEN_WEATHER == 1 +static NWSWeather::XMLItem_T WeatherData[] = { + {"lastupdate", NWSWeather::isString}, //<lastupdate value="2019-01-09T00:15:00"/> + {"city", NWSWeather::isString}, //<city id="4880889" name="Waterloo"> + {"weather", NWSWeather::isString}, //<weather number="802" value="scattered clouds" icon="03n"/> + {"temperature", NWSWeather::isFloat}, //<temperature value="27.3" min="21.2" max="32" unit="fahrenheit"/> + {"humidity", NWSWeather::isInt}, //<humidity value="68" unit="%"/> + {"direction", NWSWeather::isInt}, //<direction value="310" code="NW" name="Northwest"/> + {"speed", NWSWeather::isFloat}, //<speed value="26.4" name="Storm"/> + {"pressure", NWSWeather::isInt}, //<pressure value="1021" unit="hPa"/> + {"visibility", NWSWeather::isInt}, //<visibility value="16093"/> + {"sun*rise", NWSWeather::isString}, //<sun rise="2019-01-09T13:38:27" set="2019-01-09T22:54:45"/> + {"sun*set", NWSWeather::isString}, //<sun rise="2019-01-09T13:38:27" set="2019-01-09T22:54:45"/> +}; +//<current> +//<coord lon="-92.34" lat="42.49"/> +//<country>US</country> +//</city> +//<wind> +//<gusts value="19"/> +//</wind> +//<clouds value="40" name="scattered clouds"/> +//<precipitation mode="no"/> +//</current> +#endif #define MAXPARAMLEN 23 @@ -106,7 +132,11 @@ return WeatherItemCount; } +#if WEATHER_GOV == 1 NWSWeather::NWSReturnCode_T NWSWeather::get(const char * site, int responseSize) +#elif OPEN_WEATHER == 1 +NWSWeather::NWSReturnCode_T NWSWeather::get(const char * site, const char * userid, int responseSize) +#endif { HTTPClient http; NWSReturnCode_T retCode = nomemory; @@ -117,13 +147,25 @@ if (!message) ERR("failed to swMalloc(%d)", responseSize); while (message) { + #if WEATHER_GOV == 1 + //https://www.weather.gov/data/current_obs/<loc_code>.xml + // ++++ int n = strlen(m_baseurl) + strlen(site) + 5; - + #elif OPEN_WEATHER == 1 + //http://api.openweathermap.org/data/2.5/weather?mode=xml&units=imperial&id=<loc_code>&APPID=<user_id> + // ++++ +++++++ + int n = strlen(m_baseurl) + 4 + strlen(site) + 7 + strlen(userid) + 1; + #endif url = (char *)swMalloc(n); if (url) { - strcpy(url, m_baseurl); - strcat(url, site); - strcat(url, ".xml"); + #if WEATHER_GOV == 1 + //strcpy(url, m_baseurl); + //strcat(url, site); + //strcat(url, ".xml"); + sprintf(url, "%s%s%s.xml", m_baseurl, site); + #elif OPEN_WEATHER == 1 + sprintf(url, "%s&id=%s&APPID=%s", m_baseurl, site, userid); + #endif INFO(" url: %s", url); http.setMaxRedirections(3); http.customHeaders(hdrs, HDR_PAIRS); @@ -276,56 +318,85 @@ NWSWeather::NWSReturnCode_T NWSWeather::ParseWeatherRecord(char * p) { // <tag_name>value</tag_name> - // p1 p2 p3 - char *p1, *p2, *p3; + // pKey pValue + char *pKey, *pValue, *pX; int i; int n; int count = WeatherItemCount; + bool parseIt = false; INFO("ParseWeatherRecord(%s)", p); - p1 = strchr(p, '<'); // Pattern Matching <key>value</key> - if (p1++) { - p2 = strchr(p1+1, '>'); - if (p2) { - p3 = strchr(p2+1, '<'); - if (p3) { - *p2++ = '\0'; - *p3 = '\0'; - for (i=0; i<count; i++) { - if (strcmp(p1, WeatherData[i].name) == 0) { - switch(WeatherData[i].typeis) { - case isFloat: - WeatherData[i].value.fValue = atof(p2); - WeatherData[i].updated = true; - break; - case isInt: - WeatherData[i].value.iValue = atoi(p2); - WeatherData[i].updated = true; - break; - case isString: - if (WeatherData[i].value.sValue) - swFree(WeatherData[i].value.sValue); - n = strlen(p2)+1; - INFO(" pre- swMalloc(%d)", n); - WeatherData[i].value.sValue = (char *)swMalloc(n); - INFO(" post-swMalloc"); - if (WeatherData[i].value.sValue) { - strcpy(WeatherData[i].value.sValue, p2); - WeatherData[i].updated = true; - } else { - ERR("failed to swMalloc(%d)", n); - break; - } - break; - default: - ERR("unknown type"); - return badparameter; - //break; + #if WEATHER_GOV == 1 + // Pattern Matching <key>value</key> + // | +pValue + // +pKey + pKey = strchr(p, '<'); + if (pKey++) { + pValue = strchr(pKey+1, '>'); + if (pValue) { + p2 = strchr(pValue+1, '<'); + if (p2) { + *pValue++ = '\0'; + *p2 = '\0'; + parseIt = true; + } + } + } + #elif OPEN_WEATHER == 1 + pKey = strchr(p, '<'); + // Pattern Matching <key dontcare="something" value="thevalue" dontcare="something"/> + // | +pValue + // +pKey + if (pKey++) { + pValue = strchr(pKey+1, ' '); + if (pValue) { + *pValue++ = '\0'; + pValue = strstr(pValue, "value=\""); + if (pValue) { + pValue += 7; + pX = strchr(pValue, '"'); + if (pX) { + *pX = '\0'; + parseIt = true; + } + } + } + } + #endif + if (parseIt) { + for (i=0; i<count; i++) { + if (strcmp(pKey, WeatherData[i].name) == 0) { + switch(WeatherData[i].typeis) { + case isFloat: + WeatherData[i].value.fValue = atof(pValue); + WeatherData[i].updated = true; + break; + case isInt: + WeatherData[i].value.iValue = atoi(pValue); + WeatherData[i].updated = true; + break; + case isString: + if (WeatherData[i].value.sValue) + swFree(WeatherData[i].value.sValue); + n = strlen(pValue)+1; + INFO(" pre- swMalloc(%d)", n); + WeatherData[i].value.sValue = (char *)swMalloc(n); + INFO(" post-swMalloc"); + if (WeatherData[i].value.sValue) { + strcpy(WeatherData[i].value.sValue, pValue); + WeatherData[i].updated = true; + } else { + ERR("failed to swMalloc(%d)", n); + break; } - //INFO("pw end"); - return noerror; - } + break; + default: + ERR("unknown type"); + return badparameter; + //break; } + //INFO("pw end"); + return noerror; } } } @@ -341,7 +412,12 @@ ClearWeatherRecords(); INFO("cleared old"); while (*p) { - char * n = strchr(p, '\n'); + char * n; + #if WEATHER_GOV == 1 + n = strchr(p, '\n'); + #elif OPEN_WEATHER == 1 + n = strchr(p, '>'); + #endif if (*n) { *n = '\0'; ParseWeatherRecord(p);