-
-
Save bbx10/149bba466b1e2cd887bf to your computer and use it in GitHub Desktop.
| /**************************** | |
| The MIT License (MIT) | |
| Copyright (c) 2015 by bbx10node@gmail.com | |
| Permission is hereby granted, free of charge, to any person obtaining a copy | |
| of this software and associated documentation files (the "Software"), to deal | |
| in the Software without restriction, including without limitation the rights | |
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| copies of the Software, and to permit persons to whom the Software is | |
| furnished to do so, subject to the following conditions: | |
| The above copyright notice and this permission notice shall be included in all | |
| copies or substantial portions of the Software. | |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
| SOFTWARE. | |
| ******************************/ | |
| #include <ESP8266WiFi.h> | |
| #ifndef min | |
| #define min(x,y) (((x)<(y))?(x):(y)) | |
| #endif | |
| #ifndef max | |
| #define max(x,y) (((x)>(y))?(x):(y)) | |
| #endif | |
| #include <ArduinoJson.h> | |
| const char SSID[] = "********"; | |
| const char PASSWORD[] = "***************"; | |
| // Use your own API key by signing up for a free developer account. | |
| // http://www.wunderground.com/weather/api/ | |
| #define WU_API_KEY "****************" | |
| // Specify your favorite location one of these ways. | |
| //#define WU_LOCATION "CA/HOLLYWOOD" | |
| // US ZIP code | |
| //#define WU_LOCATION "" | |
| #define WU_LOCATION "90210" | |
| // Country and city | |
| //#define WU_LOCATION "Australia/Sydney" | |
| // 5 minutes between update checks. The free developer account has a limit | |
| // on the number of calls so don't go wild. | |
| #define DELAY_NORMAL (5*60*1000) | |
| // 20 minute delay between updates after an error | |
| #define DELAY_ERROR (20*60*1000) | |
| #define WUNDERGROUND "api.wunderground.com" | |
| // HTTP request | |
| const char WUNDERGROUND_REQ[] = | |
| "GET /api/" WU_API_KEY "/conditions/q/" WU_LOCATION ".json HTTP/1.1\r\n" | |
| "User-Agent: ESP8266/0.1\r\n" | |
| "Accept: */*\r\n" | |
| "Host: " WUNDERGROUND "\r\n" | |
| "Connection: close\r\n" | |
| "\r\n"; | |
| void setup() | |
| { | |
| Serial.begin(115200); | |
| // We start by connecting to a WiFi network | |
| Serial.println(); | |
| Serial.println(); | |
| Serial.print(F("Connecting to ")); | |
| Serial.println(SSID); | |
| WiFi.begin(SSID, PASSWORD); | |
| while (WiFi.status() != WL_CONNECTED) { | |
| delay(500); | |
| Serial.print(F(".")); | |
| } | |
| Serial.println(); | |
| Serial.println(F("WiFi connected")); | |
| Serial.println(F("IP address: ")); | |
| Serial.println(WiFi.localIP()); | |
| } | |
| static char respBuf[4096]; | |
| void loop() | |
| { | |
| // TODO check for disconnect from AP | |
| // Open socket to WU server port 80 | |
| Serial.print(F("Connecting to ")); | |
| Serial.println(WUNDERGROUND); | |
| // Use WiFiClient class to create TCP connections | |
| WiFiClient httpclient; | |
| const int httpPort = 80; | |
| if (!httpclient.connect(WUNDERGROUND, httpPort)) { | |
| Serial.println(F("connection failed")); | |
| delay(DELAY_ERROR); | |
| return; | |
| } | |
| // This will send the http request to the server | |
| Serial.print(WUNDERGROUND_REQ); | |
| httpclient.print(WUNDERGROUND_REQ); | |
| httpclient.flush(); | |
| // Collect http response headers and content from Weather Underground | |
| // HTTP headers are discarded. | |
| // The content is formatted in JSON and is left in respBuf. | |
| int respLen = 0; | |
| bool skip_headers = true; | |
| while (httpclient.connected() || httpclient.available()) { | |
| if (skip_headers) { | |
| String aLine = httpclient.readStringUntil('\n'); | |
| //Serial.println(aLine); | |
| // Blank line denotes end of headers | |
| if (aLine.length() <= 1) { | |
| skip_headers = false; | |
| } | |
| } | |
| else { | |
| int bytesIn; | |
| bytesIn = httpclient.read((uint8_t *)&respBuf[respLen], sizeof(respBuf) - respLen); | |
| Serial.print(F("bytesIn ")); Serial.println(bytesIn); | |
| if (bytesIn > 0) { | |
| respLen += bytesIn; | |
| if (respLen > sizeof(respBuf)) respLen = sizeof(respBuf); | |
| } | |
| else if (bytesIn < 0) { | |
| Serial.print(F("read error ")); | |
| Serial.println(bytesIn); | |
| } | |
| } | |
| delay(1); | |
| } | |
| httpclient.stop(); | |
| if (respLen >= sizeof(respBuf)) { | |
| Serial.print(F("respBuf overflow ")); | |
| Serial.println(respLen); | |
| delay(DELAY_ERROR); | |
| return; | |
| } | |
| // Terminate the C string | |
| respBuf[respLen++] = '\0'; | |
| Serial.print(F("respLen ")); | |
| Serial.println(respLen); | |
| //Serial.println(respBuf); | |
| if (showWeather(respBuf)) { | |
| delay(DELAY_NORMAL); | |
| } | |
| else { | |
| delay(DELAY_ERROR); | |
| } | |
| } | |
| bool showWeather(char *json) | |
| { | |
| StaticJsonBuffer<3*1024> jsonBuffer; | |
| // Skip characters until first '{' found | |
| // Ignore chunked length, if present | |
| char *jsonstart = strchr(json, '{'); | |
| //Serial.print(F("jsonstart ")); Serial.println(jsonstart); | |
| if (jsonstart == NULL) { | |
| Serial.println(F("JSON data missing")); | |
| return false; | |
| } | |
| json = jsonstart; | |
| // Parse JSON | |
| JsonObject& root = jsonBuffer.parseObject(json); | |
| if (!root.success()) { | |
| Serial.println(F("jsonBuffer.parseObject() failed")); | |
| return false; | |
| } | |
| // Extract weather info from parsed JSON | |
| JsonObject& current = root["current_observation"]; | |
| const float temp_f = current["temp_f"]; | |
| Serial.print(temp_f, 1); Serial.print(F(" F, ")); | |
| const float temp_c = current["temp_c"]; | |
| Serial.print(temp_c, 1); Serial.print(F(" C, ")); | |
| const char *humi = current[F("relative_humidity")]; | |
| Serial.print(humi); Serial.println(F(" RH")); | |
| const char *weather = current["weather"]; | |
| Serial.println(weather); | |
| const char *pressure_mb = current["pressure_mb"]; | |
| Serial.println(pressure_mb); | |
| const char *observation_time = current["observation_time_rfc822"]; | |
| Serial.println(observation_time); | |
| // Extract local timezone fields | |
| const char *local_tz_short = current["local_tz_short"]; | |
| Serial.println(local_tz_short); | |
| const char *local_tz_long = current["local_tz_long"]; | |
| Serial.println(local_tz_long); | |
| const char *local_tz_offset = current["local_tz_offset"]; | |
| Serial.println(local_tz_offset); | |
| return true; | |
| } |
instead of defining location, you can just put in autoip
where do you download the esp library?
Basic Infos
i am writing a code that give weather forecast from wunderground.com website with HTTP request, and i want send to me this forecast in telegram. i use UniversalTelegramBot library to send message in telegram. so this code have to part:
1- give weather forecast from wunderground.com
2- send this forecast in telegram Bot
Each part work as well , but when i merge two part i give Exception (29) error :(
Hardware
Hardware: NodeMcu Lua WIFI Board Based on ESP8266 CP2102 Module (ESP-12E)
Core Version: I do not know!!!
because i flash my esp with ESP8266Flasher.exe
my setings in ESP8266Flasher is in this picture:
Settings in IDE
Module: Adafruit HUZZAH esp8266
Flash Size: 4MB(3MB SPIFFS)
CPU Frequency: 80Mhz
Upload Using: SERIAL 115200
Sketch
Debug Messages
Thank you for the code! Everything work fine for me.
Maybe you can help with one question: "how can correct parse /forecast/ .json?"
Compiling your sketch on my Arduino IDE, I encountered errors in the part concerning Json (upgrade from Json 5 to Json 6 was the message on IDE!).
I made some changes to the sketch, as follow:
< bool showWeather (char * json)
{
StaticJsonDocument <3 * 1024> doc;
// Skip characters until first '{' found
// Ignore chunked length, if present
char * jsonstart = strchr (json, '{');
if (jsonstart == NULL) {
Serial.println (F ("JSON data missing"));
return false;
}
json = jsonstart;
// Parse JSON
// JsonObject & root = doc.parseObject (json);
DeserializationError error = deserializeJson (doc, json);
if (error) {
Serial.print ("deserializeJson () failed with code";
Serial.println (error.c_str ());
return false;
}
// Extract weather info from parsed JSON
JsonObject current = doc ["current_observation"; >
and no more errors.
Then, after uploaded the sketch on my nodeMCU, on Serial monitor I get:
11:18:46.083 -> Connecting to api.wunderground.com
11:18:46.130 -> GET /api/030daeaxxxxxxxxxxxxxxx154fuyt6/conditions/q/Italy/Casacalenda.json HTTP/1.1
11:18:46.130 -> User-Agent: ESP8266/0.1
11:18:46.130 -> Accept: /
11:18:46.130 -> Host: api.wunderground.com
11:18:46.130 -> Connection: close
11:18:46.130 ->
11:18:46.516 -> bytesIn 179
11:18:46.516 -> respLen 180
11:18:46.516 -> JSON data missing
11:21:46.521 -> Connecting to api.wunderground.com
11:21:46.568 -> GET /api/030daeaxxxxxxxxxxxx5yut0f6/conditions/q/Italy/Casacalenda.json HTTP/1.1
Could you help me? I'm a beginner.
Thank you!
Apparently, the Weather Underground API was shut down back in 2018:
https://apicommunity.wunderground.com/weatherapi/topics/end-of-service-for-the-weather-underground-api
so this sketch cannot work.
OpenWeatherMap offers similar functionality and free APIs (for infrequent use).
Maybe worth trying?

Hello,
I am thinking of doing a project with the Adafruit Feather HUZZAH with ESP8266.
Will this code work with this development board?
Thanks in advance!