准备使用ESP8266制作一个可以显示天气预报的桌面摆件,可以实现实时网络时钟,手机WiFi配置,自动IP城市定位,获取当前天气与三天天气预报
/**********************************************************************
程序名称/Program name : ESP-12F 获取网络天气
团队/Team : None
作者/Author : 爱电子的梦兮
日期/Date(YYYYMMDD : 2023/8/29
程序目的/Purpose :
本程序旨在通过手机配置WIFI后根据IP地址自动获取城市ID然后获取当地天气信息
如需了解本程序的详细说明,请参考以下函数:
***********************************************************************/
#include <Arduino.h>
#include <ESP8266WiFi.h> //HTTP HTTPS
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h> //解析数据
#include <DNSServer.h> //手机配置连接WIFI
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
const char* GaoFen_KEY = "1wxxjw7NIdB0ZTIPFHiNH7lR3fTXXXXX";//高分天气秘钥(自己去官网注册)
String City = "Taiyuan"; //保存城市IP 自动获取,获取失败则默认Taiyuan
String CityID = "101100101"; //保存城市ID
//天气信息:
String code;
float temp;
struct Daily_Fcsts{
String code_day;
String code_night;
int8_t high;
int8_t low;
String date;
} today,tomorrow,acquired;
struct tm* timeInfo; //时间信息
char send_Json_buff[128];
void wificonnect(void);
void GetTime(void);
void GetCityIP(void);
void GetCityID(void);
void GetCurrentWeather(void);
void GetForeWeather(void);
void setup()
{
Serial.begin(115200); //打印调试数据
wificonnect(); //WIFI连接
configTime(8*3600, 0*60, "ntp.ntsc.ac.cn", "ntp1.aliyun.com"); //npt获取时间
delay(1000); //等待WIFI稳定
GetTime();
GetCityIP();
GetCityID();
GetCurrentWeather();
GetForeWeather();
}
void loop()
{
}
// WIFI连接
void wificonnect()
{
// 建立WiFiManager对象
WiFiManager wifiManager;
// 自动连接WiFi。以下语句的参数是连接ESP8266时的WiFi名称
wifiManager.autoConnect("CW32 LPow Clock");
Serial.print("WiFi Connected!");
delay(500);
}
//获取时间
void GetTime(void)
{
time_t now; //实例化时间
now = time(nullptr);
timeInfo = localtime(&now);
}
void GetCityIP() //步骤1
{
WiFiClient client;
HTTPClient http;
String url = "http://ip-api.com/json/"; //获取IP
http.begin(client,url);
//启动连接并发送HTTP请求
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) { //服务器响应
String responsePayload = http.getString();
Serial.println(responsePayload); //打印JSON数据
//Cjson解析
DynamicJsonDocument JsonBuf(1024);
deserializeJson(JsonBuf, responsePayload);
City = JsonBuf["city"].as<String>(); //获取到IP地址(拼音,如:chongqing)
//Serial.println(City);
} else { //服务器不响应
Serial.print("HTTP GET IP ERROR!");
}
http.end();//关闭ESP8266与服务器连接
}
void GetCityID(void) //步骤2
{
WiFiClient client;
HTTPClient http;
//获取城市ID
String url = "http://gfapi.mlogcn.com/function/v001/city?location="+City+"&items=10&area=china&language=CHN&withTz=false&withPoi=false&key="+GaoFen_KEY+"&output_type=json";
http.begin(client,url);
//启动连接并发送HTTP请求
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) { //服务器响应
String responsePayload = http.getString();
Serial.println(responsePayload); //打印JSON数据
//Cjson解析
DynamicJsonDocument JsonBuf(1024);
deserializeJson(JsonBuf, responsePayload);
JsonObject areaList_0 = JsonBuf["areaList"][0];
CityID = areaList_0["areacode"].as<String>();
//Serial.println(CityID);
} else { //服务器不响应
Serial.print("HTTP GET ID ERROR!");
}
http.end();//关闭ESP8266与服务器连接
}
//获取当地当前天气
void GetCurrentWeather() //步骤3
{
//https协议
std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
client->setInsecure();
HTTPClient https;
//高分天气API
String url = "https://gfapi.mlogcn.com/weather/v001/now?areacode="+CityID+"&key="+GaoFen_KEY+"&output_type=json";
https.begin(*client, url); //连接服务器
int httpCode = https.GET();
if(httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = https.getString();
Serial.println(payload); //打印JSON数据
DynamicJsonDocument JsonBuf(1024);
deserializeJson(JsonBuf, payload);
temp = JsonBuf["result"]["realtime"]["temp"].as<float>();
code = JsonBuf["result"]["realtime"]["code"].as<String>();
}
else Serial.println("HTTP GET Weather ERROR!");
https.end();
}
//获取当地3天天气预报
void GetForeWeather() //同步骤3
{
//https协议
std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
client->setInsecure();
HTTPClient https;
//高分天气API
String url = "https://gfapi.mlogcn.com/weather/v001/day?areacode="+CityID+"&days=3&key="+GaoFen_KEY+"&output_type=json";
https.begin(*client, url); //连接服务器
int httpCode = https.GET();
if(httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = https.getString();
Serial.println(payload); //打印JSON数据
DynamicJsonDocument JsonBuf(1024);
deserializeJson(JsonBuf, payload);
JsonObject daily_fcsts_0= JsonBuf["result"]["daily_fcsts"][0];
JsonObject daily_fcsts_1= JsonBuf["result"]["daily_fcsts"][1];
JsonObject daily_fcsts_2= JsonBuf["result"]["daily_fcsts"][2];
today.code_day = daily_fcsts_0["code_day"].as<String>();
today.code_night = daily_fcsts_0["code_night"].as<String>();
today.high = daily_fcsts_0["high"].as<int>();
today.low = daily_fcsts_0["low"].as<int>();
today.date = daily_fcsts_0["date"].as<String>();
tomorrow.code_day = daily_fcsts_1["code_day"].as<String>();
tomorrow.code_night = daily_fcsts_1["code_night"].as<String>();
tomorrow.high = daily_fcsts_1["high"].as<int>();
tomorrow.low = daily_fcsts_1["low"].as<int>();
tomorrow.date = daily_fcsts_1["date"].as<String>();
acquired.code_day = daily_fcsts_2["code_day"].as<String>();
acquired.code_night = daily_fcsts_2["code_night"].as<String>();
acquired.high = daily_fcsts_2["high"].as<int>();
acquired.low = daily_fcsts_2["low"].as<int>();
acquired.date = daily_fcsts_2["date"].as<String>();
}
else Serial.println("HTTP GET Weather ERROR!");
https.end();
}