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:
- 18:699590fd8856
- Parent:
- 17:99f09cc697fb
- Child:
- 19:00af774c9b72
diff -r 99f09cc697fb -r 699590fd8856 NWSWeather.cpp --- a/NWSWeather.cpp Wed Jan 09 12:39:06 2019 +0000 +++ b/NWSWeather.cpp Mon Jan 14 03:21:13 2019 +0000 @@ -46,63 +46,12 @@ }; #define HDR_PAIRS 3 -#if WEATHER_GOV == 1 -static NWSWeather::XMLItem_T WeatherData[] = { - {"observation_time_rfc822", NWSWeather::isString}, // - {"suggested_pickup", NWSWeather::isInt}, - {"suggested_pickup_period", NWSWeather::isInt}, - {"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}, // - {"pressure_in", NWSWeather::isFloat}, - {"dewpoint_f", NWSWeather::isFloat}, - {"dewpoint_c", NWSWeather::isFloat}, - {"windchill_f", NWSWeather::isFloat}, - {"windchill_c", 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 - -#define WeatherItemCount (sizeof(WeatherData)/sizeof(WeatherData[0])) - -NWSWeather::NWSWeather(const char * baseURL) : m_baseurl(0) +NWSWeather::NWSWeather(XMLItem_T * pList, int count) : m_baseurl(0) { - setAlternateURL(baseURL); + WeatherData = pList; + WeatherItemCount = count; + setAlternateURL(DEF_URL); } NWSWeather::~NWSWeather() @@ -159,9 +108,6 @@ url = (char *)swMalloc(n); if (url) { #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); @@ -221,7 +167,7 @@ { if (name) { for (int i=0; i < WeatherItemCount; i++) { - if (strcmp(name, WeatherData[i].name) == 0) { + if (strcmp(name, WeatherData[i].key) == 0) { if (WeatherData[i].updated) return noerror; else @@ -236,7 +182,7 @@ NWSWeather::NWSReturnCode_T NWSWeather::getParam(uint16_t i, char *name, Value_T *value, TypeOf_T *typeis) { if (i < WeatherItemCount) { - *name = *WeatherData[i].name; + *name = *WeatherData[i].key; *value = WeatherData[i].value; if (typeis) *typeis = WeatherData[i].typeis; @@ -249,12 +195,20 @@ NWSWeather::NWSReturnCode_T NWSWeather::getParam(const char *name, Value_T *value, TypeOf_T *typeis) { + return getParam(name, NULL, value, typeis); +} + + +NWSWeather::NWSReturnCode_T NWSWeather::getParam(const char *name, const char * param, Value_T *value, TypeOf_T *typeis) +{ for (int i=0; i < WeatherItemCount; i++) { - if (strcmp(name, WeatherData[i].name) == 0) { - *value = WeatherData[i].value; - if (typeis) - *typeis = WeatherData[i].typeis; - return noerror; + if (strcmp(name, WeatherData[i].key) == 0) { + if (param == NULL || strcmp(param, WeatherData[i].param) == 0) { + *value = WeatherData[i].value; + if (typeis) + *typeis = WeatherData[i].typeis; + return noerror; + } } } return badparameter; @@ -292,19 +246,21 @@ void NWSWeather::PrintWeatherRecord(uint16_t i) { if (i < WeatherItemCount) { + printf("%23s::%-10s = ", WeatherData[i].key, WeatherData[i].param); switch(WeatherData[i].typeis) { case isFloat: - printf("%23s = %f\r\n", WeatherData[i].name, WeatherData[i].value.fValue); + printf("%f", WeatherData[i].value.fValue); break; case isInt: - printf("%23s = %d\r\n", WeatherData[i].name, WeatherData[i].value.iValue); + printf("%d", WeatherData[i].value.iValue); break; case isString: - printf("%23s = %s\r\n", WeatherData[i].name, WeatherData[i].value.sValue); + printf("%s", WeatherData[i].value.sValue); break; default: break; } + printf("\r\n"); } } @@ -315,8 +271,107 @@ } } +NWSWeather::NWSReturnCode_T NWSWeather::ExtractParam(int i, char * pValue, char * pEnd) { + int n; + + INFO("ExtractParam(%d, ...)", i); + switch(WeatherData[i].typeis) { + case isFloat: + WeatherData[i].value.fValue = (float)atof(pValue); + WeatherData[i].updated = true; + INFO("%f", WeatherData[i].value.fValue); + break; + case isInt: + WeatherData[i].value.iValue = atoi(pValue); + WeatherData[i].updated = true; + INFO("%d", WeatherData[i].value.iValue); + break; + case isString: + if (WeatherData[i].value.sValue) + swFree(WeatherData[i].value.sValue); + n = pEnd - pValue; + WeatherData[i].value.sValue = (char *)swMalloc(n+1); + if (WeatherData[i].value.sValue) { + strncpy(WeatherData[i].value.sValue, pValue, n); + WeatherData[i].value.sValue[n] = '\0'; + WeatherData[i].updated = true; + INFO(" info '%s'", WeatherData[i].value.sValue); + } else { + ERR("failed to swMalloc(%d)", n); + return nomemory; + } + break; + default: + ERR("unknown type"); + return badparameter; + //break; + } + INFO("..."); + return noerror; +} + NWSWeather::NWSReturnCode_T NWSWeather::ParseWeatherRecord(char * p) { + #if 1 + // Pattern Matching <thekey dontcare="something" value="thevalue"/> + // | | |------| | | + // | | | | +pEnd + // | +pKeyE +pVal +pValE + // +pKey + // + // <thekey>theValue</thekey> + // | || | | + // | || | +pEnd + // | |+pVal +pValE + // | +pKeyE + // +pKey + // + char *pKey, *pEnd; + char *pVal = NULL; + char *pValE = NULL; + + p = strchr(p, '<'); + while (p) { + //INFO("ParseWeatherRecord \n%s\n", p); + p++; // Advance past the '<' + for (int i=0; i<WeatherItemCount; i++) { + //INFO("\n check %s::%s", WeatherData[i].key, WeatherData[i].param); + pKey = strstr(p, WeatherData[i].key); + if (pKey && pKey == p && *(pKey-1) == '<') { + //INFO(" key %s", pKey); + if (WeatherData[i].param && WeatherData[i].param[0]) { + // <thekey dontcare="something" value="thevalue"/> + pEnd = strchr(pKey, '/'); + if (pEnd) { + pVal = strstr(pKey, WeatherData[i].param); + if (pVal && pVal < pEnd) { + pVal = strchr(pVal, '"'); + if (pVal) { + pVal++; + //INFO(" val %s", pVal); + pValE = strchr(pVal, '"'); + ExtractParam(i, pVal, pValE); + INFO("Key %s::%s", WeatherData[i].key, WeatherData[i].param); + } + } + } + } else { + // <thekey>theValue</key> + pVal = strchr(pKey, '>'); + if (pVal) { + pVal++; + pValE = strchr(pVal, '<'); + if (pValE && *(pValE+1) == '/') { + ExtractParam(i, pVal, pValE); + INFO("Key %s", WeatherData[i].key); + } + } + } + } + } + p = strchr(p, '<'); + } + #else // <tag_name>value</tag_name> // pKey pValue char *pKey, *pValue, *pX; @@ -365,7 +420,7 @@ #endif if (parseIt) { for (i=0; i<count; i++) { - if (strcmp(pKey, WeatherData[i].name) == 0) { + if (strcmp(pKey, WeatherData[i].key) == 0) { switch(WeatherData[i].typeis) { case isFloat: WeatherData[i].value.fValue = atof(pValue); @@ -395,36 +450,18 @@ return badparameter; //break; } - //INFO("pw end"); return noerror; } } } - //INFO("pw end"); + #endif return noparamfound; } void NWSWeather::ParseWeatherXML(char * message) { - char * p = message; + char * p = strchr(message, '<'); - INFO("ParseWeatherXML: %s", p); ClearWeatherRecords(); - INFO("cleared old"); - while (*p) { - char * n; - #if WEATHER_GOV == 1 - n = strchr(p, '\n'); - #elif OPEN_WEATHER == 1 - n = strchr(p, '>'); - #endif - if (*n) { - *n = '\0'; - ParseWeatherRecord(p); - p = n + 1; - } else { - ParseWeatherRecord(p); - break; - } - } + ParseWeatherRecord(p); }