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:
- 0:4435c965d95d
- Child:
- 1:e077d6502c94
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NWSWeather.cpp Sun Mar 16 15:37:16 2014 +0000 @@ -0,0 +1,259 @@ + +#include "NWSWeather.h" + + +static XMLItem_T WeatherData[] = { + {"observation_time_rfc822", isString, false, NULL}, + {"suggested_pickup", isString, false, NULL}, + {"suggested_pickup_period", isInt, false, 0}, + {"location", isString, false, NULL}, + {"weather", isString, false, NULL}, + {"temp_f", isFloat, false, 0}, + {"temp_c", isFloat, false, 0}, + {"relative_humidity", isInt, false, 0}, + {"wind_degrees", isInt, false, 0}, + {"wind_mph", isFloat, false, 0}, + {"pressure_mb", isFloat}, + {"pressure_in", isFloat, false, 0}, + {"dewpoint_f", isFloat}, + {"dewpoint_c", isFloat}, + {"windchill_f", isInt, false, 0}, + {"windchill_c", isInt, false, 0}, + {"visibility_mi", isFloat}, + {"icon_url_base", isString, false, NULL}, + {"icon_url_name", isString, false, NULL}, + {"latitude", isFloat, false, 0}, + {"longitude", isFloat, false, 0}, +}; + +#define MAXPARAMLEN 23 + +#define WeatherItemCount (sizeof(WeatherData)/sizeof(WeatherData[0])) + +NWSWeather::NWSWeather(const char * baseURL) +{ + setAlternateURL(baseURL); +} + +NWSWeather::~NWSWeather() +{ + ClearWeatherRecords(); +} + +NWSReturnCode_T NWSWeather::setAlternateURL(const char * baseURL) +{ + if (m_baseurl) + free(m_baseurl); + m_baseurl = (char *)malloc(strlen(baseURL)+1); + if (m_baseurl) + strcpy(m_baseurl, baseURL); + else { + return nomemory; + } + ClearWeatherRecords(); + return noerror; +} + +uint16_t NWSWeather::count(void) +{ + return WeatherItemCount; +} + +NWSReturnCode_T NWSWeather::get(const char * site, int responseSize) +{ + Timer timer; + char *message = (char *)malloc(responseSize); + + if (message) { + char * url = (char *)malloc(strlen(m_baseurl) + strlen(site) + 5); + if (url) { + strcpy(url, m_baseurl); + strcat(url, site); + strcat(url, ".xml"); + http.setMaxRedirections(3); + //printf("get(%s)\r\n", url); + timer.start(); + int ret = http.get(url, message, responseSize); + int elapsed = timer.read_ms(); + if (!ret) { + if (http.getHTTPResponseCode() >= 300 && http.getHTTPResponseCode() < 400) { + return noerror; // redirection that was not satisfied. + } else { + ParseWeatherXML(message); + return noerror; + } + } else { + return noresponse; + } + } else { + return nomemory; + } + } + return nomemory; +} + + +NWSReturnCode_T NWSWeather::getParam(uint16_t i, char *name, Value_T *value, TypeOf_T *typeis) +{ + if (i < WeatherItemCount) { + *name = *WeatherData[i].name; + *value = WeatherData[i].value; + if (typeis) + *typeis = WeatherData[i].typeis; + return noerror; + } else { + return badparameter; + } +} + + +NWSReturnCode_T NWSWeather::isUpdated(uint16_t i) +{ + if (i < WeatherItemCount && WeatherData[i].updated) + return noerror; + else + return noupdate; +} + + +NWSReturnCode_T NWSWeather::getParam(const char *name, Value_T *value, TypeOf_T *typeis) +{ + if (value) { + for (int i=0; i < WeatherItemCount; i++) { + //printf("Compare(%s,%s)\r\n", name, WeatherData[i].name); + if (strcmp(name, WeatherData[i].name) == 0) { + *value = WeatherData[i].value; + //printf(" assignment.\r\n"); + if (typeis) + *typeis = WeatherData[i].typeis; + return noerror; + } + } + } + return badparameter; +} + + +void NWSWeather::ClearWeatherRecords(void) +{ + int i; + int count = WeatherItemCount; + + for (i=0; i<count; i++) { + switch(WeatherData[i].typeis) { + case isFloat: + WeatherData[i].value.fValue = 0.0; + WeatherData[i].updated = false; + break; + case isInt: + WeatherData[i].value.iValue = 0; + WeatherData[i].updated = false; + break; + case isString: + if (WeatherData[i].value.sValue) { + free(WeatherData[i].value.sValue); + WeatherData[i].value.sValue = NULL; + } + WeatherData[i].updated = false; + break; + default: + break; + } + } +} + +void NWSWeather::PrintWeatherRecord(uint16_t i) +{ + if (i < WeatherItemCount) { + switch(WeatherData[i].typeis) { + case isFloat: + printf("%23s = %f\r\n", WeatherData[i].name, WeatherData[i].value.fValue); + break; + case isInt: + printf("%23s = %d\r\n", WeatherData[i].name, WeatherData[i].value.iValue); + break; + case isString: + printf("%23s = %s\r\n", WeatherData[i].name, WeatherData[i].value.sValue); + break; + default: + break; + } + } +} + +void NWSWeather::PrintAllWeatherRecords(void) +{ + for (int i=0; i<WeatherItemCount; i++) { + PrintWeatherRecord(i); + } +} + +NWSReturnCode_T NWSWeather::ParseWeatherRecord(char * p) +{ + // <tag_name>value</tag_name> + // p1 p2 p3 + char *p1, *p2, *p3; + int i; + int count = WeatherItemCount; + + //printf("::%s::\r\n", p); + p1 = strchr(p, '<'); + if (p1++) { + p2 = strchr(p1+1, '>'); + if (p2) { + p3 = strchr(p2+1, '<'); + if (p3) { + *p2++ = '\0'; + *p3 = '\0'; + //printf("tag: %s, value: %s\r\n", p1, p2); + 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) + free(WeatherData[i].value.sValue); + WeatherData[i].value.sValue = (char *)malloc(strlen(p2)+1); + if (WeatherData[i].value.sValue) { + strcpy(WeatherData[i].value.sValue, p2); + WeatherData[i].updated = true; + } + break; + default: + return badparameter; + //break; + } + //PrintWeatherRecord(i); + return noerror; + } + } + } + } + } + return noparamfound; +} + +void NWSWeather::ParseWeatherXML(char * message) +{ + char * p = message; + + ClearWeatherRecords(); + while (*p) { + char * n = strchr(p, '\n'); + if (*n) { + *n = '\0'; + ParseWeatherRecord(p); + p = n + 1; + } else { + ParseWeatherRecord(p); + break; + } + } +}