Skip to content

Commit a979b7a

Browse files
committed
Added Hourly forecast client
1 parent ec4c989 commit a979b7a

File tree

4 files changed

+413
-1
lines changed

4 files changed

+413
-1
lines changed

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ env:
1414
- PLATFORMIO_CI_SRC=examples/WeatherStationDemoExtended
1515
- PLATFORMIO_CI_SRC=examples/WeatherStationDemoExtendedDST
1616
- PLATFORMIO_CI_SRC=examples/WorldClockDemo
17-
- PLATFORMIO_CI_SRC=examples/WundergroundAlertsDemo
17+
- PLATFORMIO_CI_SRC=examples/WundergroundAlertsDemo
1818
- PLATFORMIO_CI_SRC=examples/WundergroundAstronomyDemo
1919
- PLATFORMIO_CI_SRC=examples/WundergroundConditionsDemo
2020
- PLATFORMIO_CI_SRC=examples/WundergroundForecastDemo
21+
- PLATFORMIO_CI_SRC=examples/WundergroundHourlyDemo
2122

2223
install:
2324
- pip install -U platformio
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/**The MIT License (MIT)
2+
3+
Copyright (c) 2017 by Daniel Eichhorn
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
22+
23+
See more at https://blog.squix.org
24+
*/
25+
26+
#include <Arduino.h>
27+
28+
#include <ESP8266WiFi.h>
29+
#include <JsonListener.h>
30+
#include "WundergroundHourly.h"
31+
32+
/**
33+
* Wunderground Settings
34+
*/
35+
const String WUNDERGRROUND_API_KEY = "API_KEY";
36+
const String WUNDERGR_UND_STATE_OR_COUNTRY = "CH";
37+
const String WUNDERGR_UND_CITY = "ZURICH";
38+
const String WUNDERGRROUND_LANGUAGE = "EN";
39+
const boolean IS_METRIC = true;
40+
const boolean IS_24HOURS = false;
41+
42+
// initiate the WundergoundClient
43+
WundergroundHourly wunderground(IS_METRIC, IS_24HOURS);
44+
45+
46+
/**
47+
* WiFi Settings
48+
*/
49+
const char* ESP_HOST_NAME = "esp-" + ESP.getFlashChipId();
50+
const char* WIFI_SSID = "yourssid";
51+
const char* WIFI_PASSWORD = "yourpassw0rd";
52+
53+
// initiate the WifiClient
54+
WiFiClient wifiClient;
55+
56+
57+
58+
/**
59+
* Helping funtions
60+
*/
61+
void connectWifi() {
62+
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
63+
Serial.print("Connecting to ");
64+
Serial.println(WIFI_SSID);
65+
while (WiFi.status() != WL_CONNECTED) {
66+
delay(500);
67+
Serial.print(".");
68+
}
69+
Serial.println("");
70+
Serial.println("WiFi connected!");
71+
Serial.println(WiFi.localIP());
72+
Serial.println();
73+
}
74+
75+
76+
/**
77+
* SETUP
78+
*/
79+
void setup() {
80+
Serial.begin(115200);
81+
delay(500);
82+
connectWifi();
83+
84+
Serial.println();
85+
Serial.println("\n\nNext Loop-Step: " + String(millis()) + ":");
86+
87+
WGHourly hourlies[24];
88+
wunderground.setMetric(true);
89+
wunderground.set24Hours(true);
90+
wunderground.updateHourly(hourlies, WUNDERGRROUND_API_KEY, WUNDERGRROUND_LANGUAGE, WUNDERGR_UND_STATE_OR_COUNTRY, WUNDERGR_UND_CITY);
91+
for (int i = 0; i < 24; i++) {
92+
Serial.println("------------------------------------");
93+
Serial.println("icon: " + hourlies[i].icon);
94+
Serial.println("title: " + hourlies[i].title);
95+
Serial.println("temp: " + hourlies[i].temp);
96+
Serial.println("hour: " + hourlies[i].hour);
97+
Serial.println("PoP: " + hourlies[i].PoP);
98+
}
99+
wunderground.setMetric(false);
100+
wunderground.set24Hours(false);
101+
wunderground.updateHourly(hourlies, WUNDERGRROUND_API_KEY, WUNDERGRROUND_LANGUAGE, WUNDERGR_UND_STATE_OR_COUNTRY, WUNDERGR_UND_CITY);
102+
for (int i = 0; i < 24; i++) {
103+
Serial.println("------------------------------------");
104+
Serial.println("icon: " + hourlies[i].icon);
105+
Serial.println("title: " + hourlies[i].title);
106+
Serial.println("temp: " + hourlies[i].temp);
107+
Serial.println("hour: " + hourlies[i].hour);
108+
Serial.println("PoP: " + hourlies[i].PoP);
109+
}
110+
111+
112+
Serial.println();
113+
Serial.println("---------------------------------------------------/\n");
114+
115+
}
116+
117+
118+
/**
119+
* LOOP
120+
*/
121+
void loop() {
122+
123+
}

src/WundergroundHourly.cpp

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
/**The MIT License (MIT)
2+
3+
Copyright (c) 2015 by Daniel Eichhorn
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
22+
23+
See more at http://blog.squix.ch
24+
*/
25+
26+
#include <ESP8266WiFi.h>
27+
#include <WiFiClient.h>
28+
#include <ESP8266HTTPClient.h>
29+
#include "WundergroundHourly.h"
30+
31+
WundergroundHourly::WundergroundHourly(boolean _isMetric, boolean _is24Hours) {
32+
isMetric = _isMetric;
33+
is24Hours = _is24Hours;
34+
}
35+
36+
void WundergroundHourly::setMetric(bool isMetric) {
37+
this->isMetric = isMetric;
38+
}
39+
void WundergroundHourly::set24Hours(bool is24Hours) {
40+
this->is24Hours = is24Hours;
41+
}
42+
43+
void WundergroundHourly::updateHourly(WGHourly *hourlies, String apiKey, String language, String country, String city) {
44+
doUpdate(hourlies, "http://api.wunderground.com/api/" + apiKey + "/hourly/lang:" + language + "/q/" + country + "/" + city + ".json");
45+
}
46+
47+
48+
void WundergroundHourly::updateHourlyPWS(WGHourly *hourlies, String apiKey, String language, String pws) {
49+
doUpdate(hourlies, "http://api.wunderground.com/api/" + apiKey + "/hourly/lang:" + language + "/q/pws:" + pws + ".json");
50+
}
51+
52+
void WundergroundHourly::updateHourlyZMW(WGHourly *hourlies, String apiKey, String language, String zmwCode) {
53+
doUpdate(hourlies, "http://api.wunderground.com/api/" + apiKey + "/hourly/lang:" + language + "/q/zmw:" + zmwCode + ".json");
54+
}
55+
56+
void WundergroundHourly::doUpdate(WGHourly *hourlies, String url) {
57+
this->hourlies = hourlies;
58+
JsonStreamingParser parser;
59+
parser.setListener(this);
60+
61+
HTTPClient http;
62+
63+
http.begin(url);
64+
bool isBody = false;
65+
char c;
66+
int size;
67+
Serial.print("[HTTP] GET...\n");
68+
// start connection and send HTTP header
69+
int httpCode = http.GET();
70+
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
71+
if(httpCode > 0) {
72+
73+
74+
75+
WiFiClient * client = http.getStreamPtr();
76+
77+
while(client->connected()) {
78+
while((size = client->available()) > 0) {
79+
c = client->read();
80+
if (c == '{' || c == '[') {
81+
82+
isBody = true;
83+
}
84+
if (isBody) {
85+
parser.parse(c);
86+
}
87+
}
88+
}
89+
}
90+
this->hourlies = nullptr;
91+
}
92+
93+
void WundergroundHourly::whitespace(char c) {
94+
Serial.println("whitespace");
95+
}
96+
97+
void WundergroundHourly::startDocument() {
98+
Serial.println("start document");
99+
}
100+
101+
void WundergroundHourly::key(String key) {
102+
currentKey = String(key);
103+
104+
}
105+
106+
void WundergroundHourly::value(String value) {
107+
if (currentKey == "hour") {
108+
currentHour = value.toInt();
109+
}
110+
111+
if (is24Hours && currentKey == "hour_padded") {
112+
hourlies[currentHour].hour = value + ":00";
113+
}
114+
if (!is24Hours && currentKey == "civil") {
115+
hourlies[currentHour].hour = value;
116+
}
117+
118+
if (currentKey == "icon") {
119+
hourlies[currentHour].icon = value;
120+
}
121+
if (currentKey == "condition") {
122+
hourlies[currentHour].title = value;
123+
}
124+
125+
126+
if (currentParent == "temp" && currentKey == "english" && !isMetric) {
127+
hourlies[currentHour].temp = value;
128+
}
129+
if (currentParent == "temp" && currentKey == "metric" && isMetric) {
130+
hourlies[currentHour].temp = value;
131+
}
132+
133+
if (currentKey == "pop") {
134+
hourlies[currentHour].PoP = value;
135+
}
136+
137+
}
138+
139+
void WundergroundHourly::endArray() {
140+
141+
}
142+
143+
144+
void WundergroundHourly::startObject() {
145+
currentParent = currentKey;
146+
}
147+
148+
void WundergroundHourly::endObject() {
149+
currentParent = "";
150+
}
151+
152+
void WundergroundHourly::endDocument() {
153+
154+
}
155+
156+
void WundergroundHourly::startArray() {
157+
158+
}
159+
160+
161+
162+
String WundergroundHourly::getMeteoconIcon(String iconText) {
163+
if (iconText == "chanceflurries") return "F";
164+
if (iconText == "chancerain") return "Q";
165+
if (iconText == "chancesleet") return "W";
166+
if (iconText == "chancesnow") return "V";
167+
if (iconText == "chancetstorms") return "S";
168+
if (iconText == "clear") return "B";
169+
if (iconText == "cloudy") return "Y";
170+
if (iconText == "flurries") return "F";
171+
if (iconText == "fog") return "M";
172+
if (iconText == "hazy") return "E";
173+
if (iconText == "mostlycloudy") return "Y";
174+
if (iconText == "mostlysunny") return "H";
175+
if (iconText == "partlycloudy") return "H";
176+
if (iconText == "partlysunny") return "J";
177+
if (iconText == "sleet") return "W";
178+
if (iconText == "rain") return "R";
179+
if (iconText == "snow") return "W";
180+
if (iconText == "sunny") return "B";
181+
if (iconText == "tstorms") return "0";
182+
183+
if (iconText == "nt_chanceflurries") return "F";
184+
if (iconText == "nt_chancerain") return "7";
185+
if (iconText == "nt_chancesleet") return "#";
186+
if (iconText == "nt_chancesnow") return "#";
187+
if (iconText == "nt_chancetstorms") return "&";
188+
if (iconText == "nt_clear") return "2";
189+
if (iconText == "nt_cloudy") return "Y";
190+
if (iconText == "nt_flurries") return "9";
191+
if (iconText == "nt_fog") return "M";
192+
if (iconText == "nt_hazy") return "E";
193+
if (iconText == "nt_mostlycloudy") return "5";
194+
if (iconText == "nt_mostlysunny") return "3";
195+
if (iconText == "nt_partlycloudy") return "4";
196+
if (iconText == "nt_partlysunny") return "4";
197+
if (iconText == "nt_sleet") return "9";
198+
if (iconText == "nt_rain") return "7";
199+
if (iconText == "nt_snow") return "#";
200+
if (iconText == "nt_sunny") return "4";
201+
if (iconText == "nt_tstorms") return "&";
202+
203+
return ")";
204+
}

0 commit comments

Comments
 (0)