David Smart / NWSWeather
Committer:
WiredHome
Date:
Sun Mar 16 15:37:16 2014 +0000
Revision:
0:4435c965d95d
Child:
1:e077d6502c94
Initial release of a NWSWeather class to gather current observation values.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 0:4435c965d95d 1
WiredHome 0:4435c965d95d 2 #include "NWSWeather.h"
WiredHome 0:4435c965d95d 3
WiredHome 0:4435c965d95d 4
WiredHome 0:4435c965d95d 5 static XMLItem_T WeatherData[] = {
WiredHome 0:4435c965d95d 6 {"observation_time_rfc822", isString, false, NULL},
WiredHome 0:4435c965d95d 7 {"suggested_pickup", isString, false, NULL},
WiredHome 0:4435c965d95d 8 {"suggested_pickup_period", isInt, false, 0},
WiredHome 0:4435c965d95d 9 {"location", isString, false, NULL},
WiredHome 0:4435c965d95d 10 {"weather", isString, false, NULL},
WiredHome 0:4435c965d95d 11 {"temp_f", isFloat, false, 0},
WiredHome 0:4435c965d95d 12 {"temp_c", isFloat, false, 0},
WiredHome 0:4435c965d95d 13 {"relative_humidity", isInt, false, 0},
WiredHome 0:4435c965d95d 14 {"wind_degrees", isInt, false, 0},
WiredHome 0:4435c965d95d 15 {"wind_mph", isFloat, false, 0},
WiredHome 0:4435c965d95d 16 {"pressure_mb", isFloat},
WiredHome 0:4435c965d95d 17 {"pressure_in", isFloat, false, 0},
WiredHome 0:4435c965d95d 18 {"dewpoint_f", isFloat},
WiredHome 0:4435c965d95d 19 {"dewpoint_c", isFloat},
WiredHome 0:4435c965d95d 20 {"windchill_f", isInt, false, 0},
WiredHome 0:4435c965d95d 21 {"windchill_c", isInt, false, 0},
WiredHome 0:4435c965d95d 22 {"visibility_mi", isFloat},
WiredHome 0:4435c965d95d 23 {"icon_url_base", isString, false, NULL},
WiredHome 0:4435c965d95d 24 {"icon_url_name", isString, false, NULL},
WiredHome 0:4435c965d95d 25 {"latitude", isFloat, false, 0},
WiredHome 0:4435c965d95d 26 {"longitude", isFloat, false, 0},
WiredHome 0:4435c965d95d 27 };
WiredHome 0:4435c965d95d 28
WiredHome 0:4435c965d95d 29 #define MAXPARAMLEN 23
WiredHome 0:4435c965d95d 30
WiredHome 0:4435c965d95d 31 #define WeatherItemCount (sizeof(WeatherData)/sizeof(WeatherData[0]))
WiredHome 0:4435c965d95d 32
WiredHome 0:4435c965d95d 33 NWSWeather::NWSWeather(const char * baseURL)
WiredHome 0:4435c965d95d 34 {
WiredHome 0:4435c965d95d 35 setAlternateURL(baseURL);
WiredHome 0:4435c965d95d 36 }
WiredHome 0:4435c965d95d 37
WiredHome 0:4435c965d95d 38 NWSWeather::~NWSWeather()
WiredHome 0:4435c965d95d 39 {
WiredHome 0:4435c965d95d 40 ClearWeatherRecords();
WiredHome 0:4435c965d95d 41 }
WiredHome 0:4435c965d95d 42
WiredHome 0:4435c965d95d 43 NWSReturnCode_T NWSWeather::setAlternateURL(const char * baseURL)
WiredHome 0:4435c965d95d 44 {
WiredHome 0:4435c965d95d 45 if (m_baseurl)
WiredHome 0:4435c965d95d 46 free(m_baseurl);
WiredHome 0:4435c965d95d 47 m_baseurl = (char *)malloc(strlen(baseURL)+1);
WiredHome 0:4435c965d95d 48 if (m_baseurl)
WiredHome 0:4435c965d95d 49 strcpy(m_baseurl, baseURL);
WiredHome 0:4435c965d95d 50 else {
WiredHome 0:4435c965d95d 51 return nomemory;
WiredHome 0:4435c965d95d 52 }
WiredHome 0:4435c965d95d 53 ClearWeatherRecords();
WiredHome 0:4435c965d95d 54 return noerror;
WiredHome 0:4435c965d95d 55 }
WiredHome 0:4435c965d95d 56
WiredHome 0:4435c965d95d 57 uint16_t NWSWeather::count(void)
WiredHome 0:4435c965d95d 58 {
WiredHome 0:4435c965d95d 59 return WeatherItemCount;
WiredHome 0:4435c965d95d 60 }
WiredHome 0:4435c965d95d 61
WiredHome 0:4435c965d95d 62 NWSReturnCode_T NWSWeather::get(const char * site, int responseSize)
WiredHome 0:4435c965d95d 63 {
WiredHome 0:4435c965d95d 64 Timer timer;
WiredHome 0:4435c965d95d 65 char *message = (char *)malloc(responseSize);
WiredHome 0:4435c965d95d 66
WiredHome 0:4435c965d95d 67 if (message) {
WiredHome 0:4435c965d95d 68 char * url = (char *)malloc(strlen(m_baseurl) + strlen(site) + 5);
WiredHome 0:4435c965d95d 69 if (url) {
WiredHome 0:4435c965d95d 70 strcpy(url, m_baseurl);
WiredHome 0:4435c965d95d 71 strcat(url, site);
WiredHome 0:4435c965d95d 72 strcat(url, ".xml");
WiredHome 0:4435c965d95d 73 http.setMaxRedirections(3);
WiredHome 0:4435c965d95d 74 //printf("get(%s)\r\n", url);
WiredHome 0:4435c965d95d 75 timer.start();
WiredHome 0:4435c965d95d 76 int ret = http.get(url, message, responseSize);
WiredHome 0:4435c965d95d 77 int elapsed = timer.read_ms();
WiredHome 0:4435c965d95d 78 if (!ret) {
WiredHome 0:4435c965d95d 79 if (http.getHTTPResponseCode() >= 300 && http.getHTTPResponseCode() < 400) {
WiredHome 0:4435c965d95d 80 return noerror; // redirection that was not satisfied.
WiredHome 0:4435c965d95d 81 } else {
WiredHome 0:4435c965d95d 82 ParseWeatherXML(message);
WiredHome 0:4435c965d95d 83 return noerror;
WiredHome 0:4435c965d95d 84 }
WiredHome 0:4435c965d95d 85 } else {
WiredHome 0:4435c965d95d 86 return noresponse;
WiredHome 0:4435c965d95d 87 }
WiredHome 0:4435c965d95d 88 } else {
WiredHome 0:4435c965d95d 89 return nomemory;
WiredHome 0:4435c965d95d 90 }
WiredHome 0:4435c965d95d 91 }
WiredHome 0:4435c965d95d 92 return nomemory;
WiredHome 0:4435c965d95d 93 }
WiredHome 0:4435c965d95d 94
WiredHome 0:4435c965d95d 95
WiredHome 0:4435c965d95d 96 NWSReturnCode_T NWSWeather::getParam(uint16_t i, char *name, Value_T *value, TypeOf_T *typeis)
WiredHome 0:4435c965d95d 97 {
WiredHome 0:4435c965d95d 98 if (i < WeatherItemCount) {
WiredHome 0:4435c965d95d 99 *name = *WeatherData[i].name;
WiredHome 0:4435c965d95d 100 *value = WeatherData[i].value;
WiredHome 0:4435c965d95d 101 if (typeis)
WiredHome 0:4435c965d95d 102 *typeis = WeatherData[i].typeis;
WiredHome 0:4435c965d95d 103 return noerror;
WiredHome 0:4435c965d95d 104 } else {
WiredHome 0:4435c965d95d 105 return badparameter;
WiredHome 0:4435c965d95d 106 }
WiredHome 0:4435c965d95d 107 }
WiredHome 0:4435c965d95d 108
WiredHome 0:4435c965d95d 109
WiredHome 0:4435c965d95d 110 NWSReturnCode_T NWSWeather::isUpdated(uint16_t i)
WiredHome 0:4435c965d95d 111 {
WiredHome 0:4435c965d95d 112 if (i < WeatherItemCount && WeatherData[i].updated)
WiredHome 0:4435c965d95d 113 return noerror;
WiredHome 0:4435c965d95d 114 else
WiredHome 0:4435c965d95d 115 return noupdate;
WiredHome 0:4435c965d95d 116 }
WiredHome 0:4435c965d95d 117
WiredHome 0:4435c965d95d 118
WiredHome 0:4435c965d95d 119 NWSReturnCode_T NWSWeather::getParam(const char *name, Value_T *value, TypeOf_T *typeis)
WiredHome 0:4435c965d95d 120 {
WiredHome 0:4435c965d95d 121 if (value) {
WiredHome 0:4435c965d95d 122 for (int i=0; i < WeatherItemCount; i++) {
WiredHome 0:4435c965d95d 123 //printf("Compare(%s,%s)\r\n", name, WeatherData[i].name);
WiredHome 0:4435c965d95d 124 if (strcmp(name, WeatherData[i].name) == 0) {
WiredHome 0:4435c965d95d 125 *value = WeatherData[i].value;
WiredHome 0:4435c965d95d 126 //printf(" assignment.\r\n");
WiredHome 0:4435c965d95d 127 if (typeis)
WiredHome 0:4435c965d95d 128 *typeis = WeatherData[i].typeis;
WiredHome 0:4435c965d95d 129 return noerror;
WiredHome 0:4435c965d95d 130 }
WiredHome 0:4435c965d95d 131 }
WiredHome 0:4435c965d95d 132 }
WiredHome 0:4435c965d95d 133 return badparameter;
WiredHome 0:4435c965d95d 134 }
WiredHome 0:4435c965d95d 135
WiredHome 0:4435c965d95d 136
WiredHome 0:4435c965d95d 137 void NWSWeather::ClearWeatherRecords(void)
WiredHome 0:4435c965d95d 138 {
WiredHome 0:4435c965d95d 139 int i;
WiredHome 0:4435c965d95d 140 int count = WeatherItemCount;
WiredHome 0:4435c965d95d 141
WiredHome 0:4435c965d95d 142 for (i=0; i<count; i++) {
WiredHome 0:4435c965d95d 143 switch(WeatherData[i].typeis) {
WiredHome 0:4435c965d95d 144 case isFloat:
WiredHome 0:4435c965d95d 145 WeatherData[i].value.fValue = 0.0;
WiredHome 0:4435c965d95d 146 WeatherData[i].updated = false;
WiredHome 0:4435c965d95d 147 break;
WiredHome 0:4435c965d95d 148 case isInt:
WiredHome 0:4435c965d95d 149 WeatherData[i].value.iValue = 0;
WiredHome 0:4435c965d95d 150 WeatherData[i].updated = false;
WiredHome 0:4435c965d95d 151 break;
WiredHome 0:4435c965d95d 152 case isString:
WiredHome 0:4435c965d95d 153 if (WeatherData[i].value.sValue) {
WiredHome 0:4435c965d95d 154 free(WeatherData[i].value.sValue);
WiredHome 0:4435c965d95d 155 WeatherData[i].value.sValue = NULL;
WiredHome 0:4435c965d95d 156 }
WiredHome 0:4435c965d95d 157 WeatherData[i].updated = false;
WiredHome 0:4435c965d95d 158 break;
WiredHome 0:4435c965d95d 159 default:
WiredHome 0:4435c965d95d 160 break;
WiredHome 0:4435c965d95d 161 }
WiredHome 0:4435c965d95d 162 }
WiredHome 0:4435c965d95d 163 }
WiredHome 0:4435c965d95d 164
WiredHome 0:4435c965d95d 165 void NWSWeather::PrintWeatherRecord(uint16_t i)
WiredHome 0:4435c965d95d 166 {
WiredHome 0:4435c965d95d 167 if (i < WeatherItemCount) {
WiredHome 0:4435c965d95d 168 switch(WeatherData[i].typeis) {
WiredHome 0:4435c965d95d 169 case isFloat:
WiredHome 0:4435c965d95d 170 printf("%23s = %f\r\n", WeatherData[i].name, WeatherData[i].value.fValue);
WiredHome 0:4435c965d95d 171 break;
WiredHome 0:4435c965d95d 172 case isInt:
WiredHome 0:4435c965d95d 173 printf("%23s = %d\r\n", WeatherData[i].name, WeatherData[i].value.iValue);
WiredHome 0:4435c965d95d 174 break;
WiredHome 0:4435c965d95d 175 case isString:
WiredHome 0:4435c965d95d 176 printf("%23s = %s\r\n", WeatherData[i].name, WeatherData[i].value.sValue);
WiredHome 0:4435c965d95d 177 break;
WiredHome 0:4435c965d95d 178 default:
WiredHome 0:4435c965d95d 179 break;
WiredHome 0:4435c965d95d 180 }
WiredHome 0:4435c965d95d 181 }
WiredHome 0:4435c965d95d 182 }
WiredHome 0:4435c965d95d 183
WiredHome 0:4435c965d95d 184 void NWSWeather::PrintAllWeatherRecords(void)
WiredHome 0:4435c965d95d 185 {
WiredHome 0:4435c965d95d 186 for (int i=0; i<WeatherItemCount; i++) {
WiredHome 0:4435c965d95d 187 PrintWeatherRecord(i);
WiredHome 0:4435c965d95d 188 }
WiredHome 0:4435c965d95d 189 }
WiredHome 0:4435c965d95d 190
WiredHome 0:4435c965d95d 191 NWSReturnCode_T NWSWeather::ParseWeatherRecord(char * p)
WiredHome 0:4435c965d95d 192 {
WiredHome 0:4435c965d95d 193 // <tag_name>value</tag_name>
WiredHome 0:4435c965d95d 194 // p1 p2 p3
WiredHome 0:4435c965d95d 195 char *p1, *p2, *p3;
WiredHome 0:4435c965d95d 196 int i;
WiredHome 0:4435c965d95d 197 int count = WeatherItemCount;
WiredHome 0:4435c965d95d 198
WiredHome 0:4435c965d95d 199 //printf("::%s::\r\n", p);
WiredHome 0:4435c965d95d 200 p1 = strchr(p, '<');
WiredHome 0:4435c965d95d 201 if (p1++) {
WiredHome 0:4435c965d95d 202 p2 = strchr(p1+1, '>');
WiredHome 0:4435c965d95d 203 if (p2) {
WiredHome 0:4435c965d95d 204 p3 = strchr(p2+1, '<');
WiredHome 0:4435c965d95d 205 if (p3) {
WiredHome 0:4435c965d95d 206 *p2++ = '\0';
WiredHome 0:4435c965d95d 207 *p3 = '\0';
WiredHome 0:4435c965d95d 208 //printf("tag: %s, value: %s\r\n", p1, p2);
WiredHome 0:4435c965d95d 209 for (i=0; i<count; i++) {
WiredHome 0:4435c965d95d 210 if (strcmp(p1, WeatherData[i].name) == 0) {
WiredHome 0:4435c965d95d 211 switch(WeatherData[i].typeis) {
WiredHome 0:4435c965d95d 212 case isFloat:
WiredHome 0:4435c965d95d 213 WeatherData[i].value.fValue = atof(p2);
WiredHome 0:4435c965d95d 214 WeatherData[i].updated = true;
WiredHome 0:4435c965d95d 215 break;
WiredHome 0:4435c965d95d 216 case isInt:
WiredHome 0:4435c965d95d 217 WeatherData[i].value.iValue = atoi(p2);
WiredHome 0:4435c965d95d 218 WeatherData[i].updated = true;
WiredHome 0:4435c965d95d 219 break;
WiredHome 0:4435c965d95d 220 case isString:
WiredHome 0:4435c965d95d 221 if (WeatherData[i].value.sValue)
WiredHome 0:4435c965d95d 222 free(WeatherData[i].value.sValue);
WiredHome 0:4435c965d95d 223 WeatherData[i].value.sValue = (char *)malloc(strlen(p2)+1);
WiredHome 0:4435c965d95d 224 if (WeatherData[i].value.sValue) {
WiredHome 0:4435c965d95d 225 strcpy(WeatherData[i].value.sValue, p2);
WiredHome 0:4435c965d95d 226 WeatherData[i].updated = true;
WiredHome 0:4435c965d95d 227 }
WiredHome 0:4435c965d95d 228 break;
WiredHome 0:4435c965d95d 229 default:
WiredHome 0:4435c965d95d 230 return badparameter;
WiredHome 0:4435c965d95d 231 //break;
WiredHome 0:4435c965d95d 232 }
WiredHome 0:4435c965d95d 233 //PrintWeatherRecord(i);
WiredHome 0:4435c965d95d 234 return noerror;
WiredHome 0:4435c965d95d 235 }
WiredHome 0:4435c965d95d 236 }
WiredHome 0:4435c965d95d 237 }
WiredHome 0:4435c965d95d 238 }
WiredHome 0:4435c965d95d 239 }
WiredHome 0:4435c965d95d 240 return noparamfound;
WiredHome 0:4435c965d95d 241 }
WiredHome 0:4435c965d95d 242
WiredHome 0:4435c965d95d 243 void NWSWeather::ParseWeatherXML(char * message)
WiredHome 0:4435c965d95d 244 {
WiredHome 0:4435c965d95d 245 char * p = message;
WiredHome 0:4435c965d95d 246
WiredHome 0:4435c965d95d 247 ClearWeatherRecords();
WiredHome 0:4435c965d95d 248 while (*p) {
WiredHome 0:4435c965d95d 249 char * n = strchr(p, '\n');
WiredHome 0:4435c965d95d 250 if (*n) {
WiredHome 0:4435c965d95d 251 *n = '\0';
WiredHome 0:4435c965d95d 252 ParseWeatherRecord(p);
WiredHome 0:4435c965d95d 253 p = n + 1;
WiredHome 0:4435c965d95d 254 } else {
WiredHome 0:4435c965d95d 255 ParseWeatherRecord(p);
WiredHome 0:4435c965d95d 256 break;
WiredHome 0:4435c965d95d 257 }
WiredHome 0:4435c965d95d 258 }
WiredHome 0:4435c965d95d 259 }