Skip to content

Commit 6d3bd3d

Browse files
committed
Added functions for weather alerts
Added additional functions to Weather Underground client for weather alerts. Also added PoP (probability of precipitation) function, and initialization function to allow setting metric flag other than at instantiation.
1 parent c71bc61 commit 6d3bd3d

File tree

2 files changed

+220
-24
lines changed

2 files changed

+220
-24
lines changed

WundergroundClient.cpp

Lines changed: 178 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ WundergroundClient::WundergroundClient(boolean _isMetric) {
3333
isMetric = _isMetric;
3434
}
3535

36+
// Added by fowlerk, 12/22/16, as an option to change metric setting other than at instantiation
37+
void WundergroundClient::initMetric(boolean _isMetric) {
38+
isMetric = _isMetric;
39+
}
40+
// end add fowlerk, 12/22/16
41+
3642
void WundergroundClient::updateConditions(String apiKey, String language, String country, String city) {
3743
isForecast = false;
3844
doUpdate("/api/" + apiKey + "/conditions/lang:" + language + "/q/" + country + "/" + city + ".json");
@@ -59,7 +65,19 @@ void WundergroundClient::updateAstronomy(String apiKey, String language, String
5965

6066
// fowlerk added
6167
void WundergroundClient::updateAlerts(String apiKey, String language, String country, String city) {
62-
isForecast = true;
68+
currentAlert = 0;
69+
activeAlertsCnt = 0;
70+
isForecast = false;
71+
isSimpleForecast = false;
72+
isCurrentObservation = false;
73+
isAlerts = true;
74+
if (country == "US") {
75+
isAlertUS = true;
76+
isAlertEU = false;
77+
} else {
78+
isAlertUS = false;
79+
isAlertEU = true;
80+
}
6381
doUpdate("/api/" + apiKey + "/alerts/lang:" + language + "/q/" + country + "/" + city + ".json");
6482
}
6583
// end fowlerk add
@@ -182,14 +200,18 @@ void WundergroundClient::value(String value) {
182200
isPM = true;
183201
}
184202
else isPM = false;
185-
sunriseTime = String(tempHour);
203+
char tempHourBuff[3] = ""; // fowlerk add for formatting, 12/22/16
204+
sprintf(tempHourBuff, "%2d", tempHour); // fowlerk add for formatting, 12/22/16
205+
sunriseTime = String(tempHourBuff); // fowlerk add for formatting, 12/22/16
186206
//sunriseTime = value;
187207
}
188208
if (currentKey == "minute") {
189-
sunriseTime += ":" + value;
190-
if (isPM) sunriseTime += "pm";
191-
else if (usePM) sunriseTime += "am";
192-
}
209+
char tempMinBuff[3] = ""; // fowlerk add for formatting, 12/22/16
210+
sprintf(tempMinBuff, "%02d", value.toInt()); // fowlerk add for formatting, 12/22/16
211+
sunriseTime += ":" + String(tempMinBuff); // fowlerk add for formatting, 12/22/16
212+
if (isPM) sunriseTime += "pm";
213+
else if (usePM) sunriseTime += "am";
214+
}
193215
}
194216

195217

@@ -201,14 +223,18 @@ void WundergroundClient::value(String value) {
201223
isPM = true;
202224
}
203225
else isPM = false;
204-
sunsetTime = String(tempHour);
226+
char tempHourBuff[3] = ""; // fowlerk add for formatting, 12/22/16
227+
sprintf(tempHourBuff, "%2d", tempHour); // fowlerk add for formatting, 12/22/16
228+
sunsetTime = String(tempHourBuff); // fowlerk add for formatting, 12/22/16
205229
// sunsetTime = value;
206230
}
207231
if (currentKey == "minute") {
208-
sunsetTime += ":" + value;
209-
if (isPM) sunsetTime += "pm";
210-
else if(usePM) sunsetTime += "am";
211-
}
232+
char tempMinBuff[3] = ""; // fowlerk add for formatting, 12/22/16
233+
sprintf(tempMinBuff, "%02d", value.toInt()); // fowlerk add for formatting, 12/22/16
234+
sunsetTime += ":" + String(tempMinBuff); // fowlerk add for formatting, 12/22/16
235+
if (isPM) sunsetTime += "pm";
236+
else if(usePM) sunsetTime += "am";
237+
}
212238
}
213239

214240
if (currentParent == "moonrise") { // Has a Parent key and 2 sub-keys
@@ -219,24 +245,31 @@ void WundergroundClient::value(String value) {
219245
isPM = true;
220246
}
221247
else isPM = false;
222-
moonriseTime = String(tempHour);
248+
char tempHourBuff[3] = ""; // fowlerk add for formatting, 12/22/16
249+
sprintf(tempHourBuff, "%2d", tempHour); // fowlerk add for formatting, 12/22/16
250+
moonriseTime = String(tempHourBuff); // fowlerk add for formatting, 12/22/16
223251
// moonriseTime = value;
224252
}
225253
if (currentKey == "minute") {
226-
moonriseTime += ":" + value;
227-
if (isPM) moonriseTime += "pm";
228-
else if (usePM) moonriseTime += "am";
229-
230-
}
254+
char tempMinBuff[3] = ""; // fowlerk add for formatting, 12/22/16
255+
sprintf(tempMinBuff, "%02d", value.toInt()); // fowlerk add for formatting, 12/22/16
256+
moonriseTime += ":" + String(tempMinBuff); // fowlerk add for formatting, 12/22/16
257+
if (isPM) moonriseTime += "pm";
258+
else if (usePM) moonriseTime += "am";
259+
}
231260
}
232261

233262
if (currentParent == "moonset") { // Not used - has a Parent key and 2 sub-keys
234263
if (currentKey == "hour") {
235-
moonsetTime = value;
236-
}
264+
char tempHourBuff[3] = ""; // fowlerk add for formatting, 12/22/16
265+
sprintf(tempHourBuff, "%2d", value.toInt()); // fowlerk add for formatting, 12/22/16
266+
moonsetTime = String(tempHourBuff); // fowlerk add for formatting, 12/22/16
267+
}
237268
if (currentKey == "minute") {
238-
moonsetTime += ":" + value;
239-
}
269+
char tempMinBuff[3] = ""; // fowlerk add for formatting, 12/22/16
270+
sprintf(tempMinBuff, "%02d", value.toInt()); // fowlerk add for formatting, 12/22/16
271+
moonsetTime += ":" + String(tempMinBuff); // fowlerk add for formatting, 12/22/16
272+
}
240273
}
241274

242275
if (currentKey == "wind_mph") {
@@ -299,6 +332,70 @@ void WundergroundClient::value(String value) {
299332
UV = value;
300333
}
301334

335+
// Active alerts...added 18-Dec-2016
336+
if (currentKey == "type" && isAlerts) {
337+
activeAlertsCnt++;
338+
currentAlert++;
339+
activeAlerts[currentAlert-1] = value;
340+
Serial.print("Alert type processed, value: "); Serial.println(activeAlerts[currentAlert-1]);
341+
}
342+
if (currentKey == "description" && isAlerts && isAlertUS) {
343+
activeAlertsText[currentAlert-1] = value;
344+
Serial.print("Alert description processed, value: "); Serial.println(activeAlertsText[currentAlert-1]);
345+
}
346+
if (currentKey == "wtype_meteoalarm_name" && isAlerts && isAlertEU) {
347+
activeAlertsText[currentAlert-1] = value;
348+
Serial.print("Alert description processed, value: "); Serial.println(activeAlertsText[currentAlert-1]);
349+
}
350+
if (currentKey == "message" && isAlerts) {
351+
activeAlertsMessage[currentAlert-1] = value;
352+
Serial.print("Alert msg length: "); Serial.println(activeAlertsMessage[currentAlert-1].length());
353+
if(activeAlertsMessage[currentAlert-1].length() >= 511) {
354+
activeAlertsMessageTrunc[currentAlert-1] = true;
355+
} else {
356+
activeAlertsMessageTrunc[currentAlert-1] = false;
357+
}
358+
Serial.print("Alert message processed, value: "); Serial.println(activeAlertsMessage[currentAlert-1]);
359+
}
360+
if (currentKey == "date" && isAlerts) {
361+
activeAlertsStart[currentAlert-1] = value;
362+
// Check last char for a "/"; the returned value sometimes includes this; if so, strip it (47 is a "/" char)
363+
if (activeAlertsStart[currentAlert-1].charAt(activeAlertsStart[currentAlert-1].length()-1) == 47) {
364+
Serial.println("...last char is a slash...");
365+
activeAlertsStart[currentAlert-1] = activeAlertsStart[currentAlert-1].substring(0,(activeAlertsStart[currentAlert-1].length()-1));
366+
}
367+
// For meteoalarms, the start field is returned with the UTC=0 by default (not used?)
368+
if (isAlertEU && activeAlertsStart[currentAlert-1] == "1970-01-01 00:00:00 GMT") {
369+
activeAlertsStart[currentAlert-1] = "<Not specified>";
370+
}
371+
Serial.print("Alert start processed, value: "); Serial.println(activeAlertsStart[currentAlert-1]);
372+
}
373+
if (currentKey == "expires" && isAlerts) {
374+
activeAlertsEnd[currentAlert-1] = value;
375+
Serial.print("Alert expiration processed, value: "); Serial.println(activeAlertsEnd[currentAlert-1]);
376+
}
377+
if (currentKey == "phenomena" && isAlerts) {
378+
activeAlertsPhenomena[currentAlert-1] = value;
379+
Serial.print("Alert phenomena processed, value: "); Serial.println(activeAlertsPhenomena[currentAlert-1]);
380+
}
381+
if (currentKey == "significance" && isAlerts && isAlertUS) {
382+
activeAlertsSignificance[currentAlert-1] = value;
383+
Serial.print("Alert significance processed, value: "); Serial.println(activeAlertsSignificance[currentAlert-1]);
384+
}
385+
// Map meteoalarm level to the field for significance for consistency (used for European alerts)
386+
if (currentKey == "level_meteoalarm" && isAlerts && isAlertEU) {
387+
activeAlertsSignificance[currentAlert-1] = value;
388+
Serial.print("Meteo alert significance processed, value: "); Serial.println(activeAlertsSignificance[currentAlert-1]);
389+
}
390+
// For meteoalarms only (European alerts); attribution must be displayed according to the T&C's of use
391+
if (currentKey == "attribution" && isAlerts) {
392+
activeAlertsAttribution[currentAlert-1] = value;
393+
// Remove some of the markup in the attribution
394+
activeAlertsAttribution[currentAlert-1].replace(" <a href='"," ");
395+
activeAlertsAttribution[currentAlert-1].replace("</a>","");
396+
activeAlertsAttribution[currentAlert-1].replace("/'>"," ");
397+
}
398+
302399
// end fowlerk add
303400

304401
if (currentKey == "dewpoint_f" && !isMetric) {
@@ -327,11 +424,21 @@ void WundergroundClient::value(String value) {
327424
}
328425

329426
// Added forecastText key following...fowlerk, 12/3/16
330-
if (currentKey == "fcttext" && isForecast && currentForecastPeriod < MAX_FORECAST_PERIODS) {
427+
if (currentKey == "fcttext" && isForecast && !isMetric && currentForecastPeriod < MAX_FORECAST_PERIODS) {
428+
forecastText[currentForecastPeriod] = value;
429+
}
430+
// Added option for metric forecast following...fowlerk, 12/22/16
431+
if (currentKey == "fcttext_metric" && isForecast && isMetric && currentForecastPeriod < MAX_FORECAST_PERIODS) {
331432
forecastText[currentForecastPeriod] = value;
332433
}
333434
// end fowlerk add, 12/3/16
334435

436+
// Added PoP (probability of precipitation) key following...fowlerk, 12/22/16
437+
if (currentKey == "pop" && isForecast && currentForecastPeriod < MAX_FORECAST_PERIODS) {
438+
PoP[currentForecastPeriod] = value;
439+
}
440+
// end fowlerk add, 12/22/16
441+
335442
// The detailed forecast period has only one forecast per day with low/high for both
336443
// night and day, starting at index 1.
337444
int dailyForecastPeriod = (currentForecastPeriod - 1) * 2;
@@ -513,6 +620,48 @@ String WundergroundClient::getUV() {
513620
String WundergroundClient::getObservationTime() {
514621
return observationTime;
515622
}
623+
624+
// Active alerts...added 18-Dec-2016
625+
String WundergroundClient::getActiveAlerts(int alertIndex) {
626+
return activeAlerts[alertIndex];
627+
}
628+
629+
String WundergroundClient::getActiveAlertsText(int alertIndex) {
630+
return activeAlertsText[alertIndex];
631+
}
632+
633+
String WundergroundClient::getActiveAlertsMessage(int alertIndex) {
634+
return activeAlertsMessage[alertIndex];
635+
}
636+
637+
bool WundergroundClient::getActiveAlertsMessageTrunc(int alertIndex) {
638+
return activeAlertsMessageTrunc[alertIndex];
639+
}
640+
641+
String WundergroundClient::getActiveAlertsStart(int alertIndex) {
642+
return activeAlertsStart[alertIndex];
643+
}
644+
645+
String WundergroundClient::getActiveAlertsEnd(int alertIndex) {
646+
return activeAlertsEnd[alertIndex];
647+
}
648+
649+
String WundergroundClient::getActiveAlertsPhenomena(int alertIndex) {
650+
return activeAlertsPhenomena[alertIndex];
651+
}
652+
653+
String WundergroundClient::getActiveAlertsSignificance(int alertIndex) {
654+
return activeAlertsSignificance[alertIndex];
655+
}
656+
657+
String WundergroundClient::getActiveAlertsAttribution(int alertIndex) {
658+
return activeAlertsAttribution[alertIndex];
659+
}
660+
661+
int WundergroundClient::getActiveAlertsCnt() {
662+
return activeAlertsCnt;
663+
}
664+
516665
// end fowlerk add
517666

518667

@@ -555,9 +704,14 @@ String WundergroundClient::getForecastMonth(int period) {
555704
}
556705

557706
String WundergroundClient::getForecastText(int period) {
558-
Serial.print("Forecast period: "); Serial.println(period);
707+
// Serial.print("Forecast period: "); Serial.println(period);
559708
return forecastText[period];
560709
}
710+
711+
// Added PoP...12/22/16
712+
String WundergroundClient::getPoP(int period) {
713+
return PoP[period];
714+
}
561715
// end fowlerk add
562716

563717

@@ -603,4 +757,4 @@ String WundergroundClient::getMeteoconIcon(String iconText) {
603757
if (iconText == "nt_tstorms") return "&";
604758

605759
return ")";
606-
}
760+
}

WundergroundClient.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ See more at http://blog.squix.ch
3131
#define MAX_FORECAST_PERIODS 20 // Changed from 7 to 12 to support 6 day / 2 screen forecast (Neptune)
3232
// Changed to 20 to support max 10-day forecast returned from 'forecast10day' API (fowlerk)
3333

34+
#define MAX_WEATHER_ALERTS 6 // The maximum number of concurrent weather alerts supported by the library
35+
3436
class WundergroundClient: public JsonListener {
3537
private:
3638
String currentKey;
@@ -71,6 +73,8 @@ class WundergroundClient: public JsonListener {
7173
boolean isSimpleForecast = false; // true; fowlerk
7274
boolean isCurrentObservation = false; // Added by fowlerk
7375
boolean isAlerts = false; // Added by fowlerk
76+
boolean isAlertUS = false; // Added by fowlerk
77+
boolean isAlertEU = false; // Added by fowlerk
7478
int currentForecastPeriod;
7579
String forecastIcon [MAX_FORECAST_PERIODS];
7680
String forecastTitle [MAX_FORECAST_PERIODS];
@@ -80,6 +84,19 @@ class WundergroundClient: public JsonListener {
8084
String forecastDay [MAX_FORECAST_PERIODS/2];
8185
String forecastMonth [MAX_FORECAST_PERIODS/2];
8286
String forecastText [MAX_FORECAST_PERIODS];
87+
String PoP [MAX_FORECAST_PERIODS];
88+
// Active alerts...added 18-Dec-2016
89+
String activeAlerts [MAX_WEATHER_ALERTS]; // For a max of 6 currently-active alerts
90+
String activeAlertsMessage [MAX_WEATHER_ALERTS]; // Alert full-text message
91+
bool activeAlertsMessageTrunc [MAX_WEATHER_ALERTS]; // Alert full-text message truncation flag
92+
String activeAlertsText [MAX_WEATHER_ALERTS]; // Alerts description text
93+
String activeAlertsStart [MAX_WEATHER_ALERTS]; // Start of alert date/time
94+
String activeAlertsEnd [MAX_WEATHER_ALERTS]; // Expiration of alert date/time
95+
String activeAlertsPhenomena [MAX_WEATHER_ALERTS]; // Alert phenomena code
96+
String activeAlertsSignificance [MAX_WEATHER_ALERTS]; // Alert significance code
97+
String activeAlertsAttribution [MAX_WEATHER_ALERTS]; // Alert significance code
98+
int activeAlertsCnt; // Number of active alerts
99+
int currentAlert; // For indexing the current active alert
83100
// end fowlerk add
84101

85102
public:
@@ -89,6 +106,8 @@ class WundergroundClient: public JsonListener {
89106
void updateForecast(String apiKey, String language, String country, String city);
90107
void updateAstronomy(String apiKey, String language, String country, String city);
91108
void updateAlerts(String apiKey, String language, String country, String city); // Added by fowlerk, 18-Dec-2016
109+
void initMetric(boolean isMetric); // Added by fowlerk, 12/22/16, as an option to change metric setting other than at instantiation
110+
92111
// JJG added
93112
String getHours();
94113
String getMinutes();
@@ -145,6 +164,29 @@ class WundergroundClient: public JsonListener {
145164
String getForecastMonth(int period);
146165

147166
String getForecastText(int period);
167+
168+
String getPoP(int period);
169+
170+
int getActiveAlertsCnt();
171+
172+
String getActiveAlerts(int alertIndex);
173+
174+
String getActiveAlertsText(int alertIndex);
175+
176+
String getActiveAlertsMessage(int alertIndex);
177+
178+
bool getActiveAlertsMessageTrunc(int alertIndex);
179+
180+
String getActiveAlertsStart(int alertIndex);
181+
182+
String getActiveAlertsEnd(int alertIndex);
183+
184+
String getActiveAlertsPhenomena(int alertIndex);
185+
186+
String getActiveAlertsSignificance(int alertIndex);
187+
188+
String getActiveAlertsAttribution(int alertIndex);
189+
148190
// end fowlerk add
149191

150192
virtual void whitespace(char c);

0 commit comments

Comments
 (0)