1 天气服务
https://www.seniverse.com/products?iid=4a8a4c16-71a3-4e94-8a49-b1680a3cb358
SVaEt7yji_44YDi3_
秘钥非常关键

1.1 JSON数据结构

https://api.seniverse.com/v3/weather/daily.json?key=SVaEt7yji_44YDi3_&location=beijing&language=zh-Hans&unit=c&start=0&days=5
{
"results": [
{
"location": {
"id": "WX4FBXXFKE4F",
"name": "北京",
"country": "CN",
"path": "北京,北京,中国",
"timezone": "Asia/Shanghai",
"timezone_offset": "+08:00"
},
"daily": [
{
"date": "2023-03-18",
"text_day": "多云",
"code_day": "4",
"text_night": "晴",
"code_night": "1",
"high": "17",
"low": "1",
"rainfall": "0.00",
"precip": "0.00",
"wind_direction": "北",
"wind_direction_degree": "0",
"wind_speed": "23.4",
"wind_scale": "4",
"humidity": "29"
},
{
"date": "2023-03-19",
"text_day": "多云",
"code_day": "4",
"text_night": "多云",
"code_night": "4",
"high": "14",
"low": "1",
"rainfall": "0.00",
"precip": "0.00",
"wind_direction": "南",
"wind_direction_degree": "180",
"wind_speed": "8.4",
"wind_scale": "2",
"humidity": "64"
},
{
"date": "2023-03-20",
"text_day": "多云",
"code_day": "4",
"text_night": "多云",
"code_night": "4",
"high": "18",
"low": "7",
"rainfall": "0.00",
"precip": "0.00",
"wind_direction": "南",
"wind_direction_degree": "180",
"wind_speed": "3.0",
"wind_scale": "1",
"humidity": "76"
}
],
"last_update": "2023-03-18T08:00:00+08:00"
}
]
}
2 详细代码
#include <string.h>
#include <sys/param.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_netif.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "esp_tls.h"
#include "esp_http_client.h"
#include "cJSON.h"
#define WiFi_STA_SSID "qkxhome"
#define WiFi_STA_PASSWORD "qkx2021&&"
#define WiFi_MAX_RETRY 15
static EventGroupHandle_t wifi_event_group;
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
static const char *WiFi_TAG = "WIFI基站20220925:获取天气信息 -> ";
static uint8_t WiFi_retry_num = 0;
static bool gl_sta_connected = false;
static uint8_t gl_sta_bssid[6];
static uint8_t gl_sta_ssid[32];
static int gl_sta_ssid_len = 0;
static bool gl_got_ip = false;
static const char *HTTP_TAG = "HTTP获取天气信息20220925 -> ";
#define MAX_HTTP_OUTPUT_BUFFER 1300
#define HOST "api.seniverse.com"
#define UserKey "SVaEt7yji_44YDi3_"
#define Location "zhengzhou"
#define Language "zh-Hans"
#define Strat "0"
#define Days "5"
static const char *RESULT_TAG = "天气信息解析数据";
static void cJSON_parse_task(char* text){
char oledText[16];
char *date,*Temp_High = NULL,*Temp_Low,*humidity,*Rainfall;
cJSON *root,*arrayItem,*subArray;
cJSON *arr_item,*sub_array_item;
cJSON *JsonDate,*JsonTemp_High,*JsonTemp_Low,*JsonHumidity,*JsonRainfall;
root = cJSON_Parse(text);
if(root!=NULL)
{
arrayItem = cJSON_GetObjectItem(root,"results")
int arr_size = cJSON_GetArraySize(arrayItem);
ESP_LOGI(HTTP_TAG, "root_arr_size: %d \n", arr_size);
arr_item = arrayItem->child;
for(int i = 0; i < arr_size; i ++){
subArray = cJSON_GetObjectItem(arr_item, "daily");
int sub_array_size = cJSON_GetArraySize(subArray);
sub_array_item = subArray->child;
ESP_LOGI(HTTP_TAG, "sub_arr_size: %d \n", sub_array_size);
for(int j = 0; j < sub_array_size; j ++){
printf("\t 一组数据解析开始 \n");
if(sub_array_item->type == cJSON_Object){
JsonDate = cJSON_GetObjectItem(sub_array_item, "date");
if(cJSON_IsString(JsonDate)){
date = JsonDate->valuestring;
sprintf(oledText, "date: %s", date);
ESP_LOGI(RESULT_TAG, "%s", oledText);
}
JsonTemp_High = cJSON_GetObjectItem(sub_array_item, "high");
if(cJSON_IsString(JsonTemp_High))
Temp_High = JsonTemp_High->valuestring;
JsonTemp_Low = cJSON_GetObjectItem(sub_array_item, "low");
if(cJSON_IsString(JsonTemp_Low)){
Temp_Low=JsonTemp_Low->valuestring;
sprintf(oledText, "Temp: %s to %s", Temp_High, Temp_Low);
ESP_LOGI(RESULT_TAG, "%s", oledText);
}
JsonHumidity = cJSON_GetObjectItem(sub_array_item, "humidity");
if(cJSON_IsString(JsonHumidity)){
humidity=JsonHumidity->valuestring;
sprintf(oledText, "Humi: %s", humidity);
ESP_LOGI(RESULT_TAG, "%s", oledText);
}
JsonRainfall = cJSON_GetObjectItem(sub_array_item, "rainfall");
if(cJSON_IsString(JsonRainfall)){
Rainfall=JsonRainfall->valuestring;
sprintf(oledText, "Rain: %s", Rainfall);
ESP_LOGI(RESULT_TAG, "%s", oledText);
}
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
sub_array_item = sub_array_item->next;
}
arr_item = arr_item -> next;
}
printf("\n");
ESP_LOGI(HTTP_TAG, "Finish");
}
cJSON_Delete(root);
}
static void http_client_task(void *pvParameters){
char output_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
int content_length = 0;
static const char *URL = "http://"HOST"/v3/weather/daily.json?" \
"key="UserKey"&location="Location \
"&language="Language \
"&unit=c&start="Strat"&days="Days;
esp_http_client_config_t config = {
.url = URL,
};
esp_http_client_handle_t client = esp_http_client_init(&config);
esp_http_client_set_method(client, HTTP_METHOD_GET);
esp_err_t err = esp_http_client_open(client, 0);
if (err != ESP_OK) {
ESP_LOGE(HTTP_TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));
} else {
content_length = esp_http_client_fetch_headers(client);
if (content_length < 0) {
ESP_LOGE(HTTP_TAG, "HTTP client fetch headers failed");
} else {
int data_read = esp_http_client_read_response(client, output_buffer, MAX_HTTP_OUTPUT_BUFFER);
if (data_read >= 0) {
ESP_LOGI(HTTP_TAG, "HTTP GET Status = %d, content_length = %d",
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
ESP_LOGI(WiFi_TAG, "\n\n\n %s \n", output_buffer);
cJSON_parse_task(output_buffer);
} else {
ESP_LOGE(HTTP_TAG, "Failed to read response");
}
}
}
esp_http_client_close(client);
vTaskDelete(NULL);
}
static void event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
if(event_base == WIFI_EVENT){
wifi_event_sta_connected_t *wifi_sta_event = (wifi_event_sta_connected_t*) event_data;
switch(event_id){
case WIFI_EVENT_STA_START:
ESP_LOGI(WiFi_TAG, "connect to AP:%s ", WiFi_STA_SSID);
esp_wifi_connect();
break;
case WIFI_EVENT_STA_CONNECTED:
ESP_LOGI(WiFi_TAG, "connected");
WiFi_retry_num = 0;
gl_sta_connected = true;
wifi_sta_event = (wifi_event_sta_connected_t*) event_data;
memcpy(gl_sta_bssid, wifi_sta_event->bssid, 6);
memcpy(gl_sta_ssid, wifi_sta_event->ssid, wifi_sta_event->ssid_len);
gl_sta_ssid_len = wifi_sta_event->ssid_len;
break;
case WIFI_EVENT_STA_DISCONNECTED:
gl_sta_connected = false;
WiFi_retry_num ++;
if(WiFi_retry_num > WiFi_MAX_RETRY){
ESP_LOGI(WiFi_TAG, "retry to connect to AP:%s ", WiFi_STA_SSID);
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, WIFI_CONNECTED_BIT);
}else{
xEventGroupSetBits(wifi_event_group, WIFI_FAIL_BIT);
}
break;
default:
break;
}
}else if(event_base == IP_EVENT){
ip_event_got_ip_t* ip_event = (ip_event_got_ip_t*) event_data;
if(event_id == IP_EVENT_STA_GOT_IP){
ESP_LOGI(WiFi_TAG, "got ip:" IPSTR, IP2STR(&ip_event->ip_info.ip));
xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_BIT);
WiFi_retry_num = 0;
gl_got_ip = true;
xTaskCreate(http_client_task, "http_client", 5120, NULL, 3, NULL);
}
}
return;
}
static void initialise_wifi(void)
{
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
assert(sta_netif);
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
wifi_config_t wifi_config= {
.sta = {
.ssid = WiFi_STA_SSID,
.password = WiFi_STA_PASSWORD,
.bssid_set = 0,
}
};
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
ESP_ERROR_CHECK( esp_wifi_start() );
ESP_LOGI(WiFi_TAG, "wifi_init_sta finished.");
EventBits_t bits = xEventGroupWaitBits(wifi_event_group,
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
pdFALSE,
pdFALSE,
portMAX_DELAY);
if (bits & WIFI_CONNECTED_BIT) {
ESP_LOGI(WiFi_TAG, "connected to ap SSID:%s password:%s",
WiFi_STA_SSID, WiFi_STA_PASSWORD);
} else if (bits & WIFI_FAIL_BIT) {
ESP_LOGI(WiFi_TAG, "Failed to connect to SSID:%s, password:%s",
WiFi_STA_SSID, WiFi_STA_PASSWORD);
} else {
ESP_LOGE(WiFi_TAG, "UNEXPECTED EVENT");
}
}
void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());
initialise_wifi();
}