ESP32 IDF 獲取天氣信息

一、注冊天氣獲取賬號我使用的知心天氣,沒有獲取天氣賬號的小伙伴可以去注冊一下,知心天氣官網:https://www.seniverse.com/取得天氣獲取的API后,可以直接在瀏覽器中訪問測試一下,如下圖所示:

ESP32 IDF 獲取天氣信息

文章插圖
這里我就不贅述了 , 稍微花點信息就可以明白天氣是怎么獲取的了 。
二、天氣信息獲取到的天氣格式是JSON的數據,直接在瀏覽器中不好觀察,所以我將它整理了一下 , 如下所示:
【ESP32 IDF 獲取天氣信息】{ "results":[{"location":{"id":"WKEZD7MXE04F","name":"貴陽","country":"CN","path":"貴陽,貴陽,貴州,中國","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},"daily":[{"date":"2022-10-24","text_day":"多云","code_day":"4","text_night":"多云","code_night":"4","high":"24","low":"12","rainfall":"0.00","precip":"0.00","wind_direction":"東南","wind_direction_degree":"135","wind_speed":"8.4","wind_scale":"2","humidity":"57"},{"date":"2022-10-25","text_day":"多云","code_day":"4","text_night":"多云","code_night":"4","high":"24","low":"14","rainfall":"0.00","precip":"0.00","wind_direction":"南","wind_direction_degree":"180","wind_speed":"8.4","wind_scale":"2","humidity":"62"},{"date":"2022-10-26","text_day":"陰","code_day":"9","text_night":"陣雨","code_night":"10","high":"24","low":"13","rainfall":"4.63","precip":"0.94","wind_direction":"南","wind_direction_degree":"180","wind_speed":"3.0","wind_scale":"1","humidity":"87"}],"last_update":"2022-10-24T08:00:00+08:00"} ]} 其中有些格式可能看不知道什么意思,不要怕,看官方的注釋,如下所示:
{"results": [{"location": {"id": "C23NB62W20TF","name": "西雅圖","country": "US","path": "西雅圖,華盛頓州,美國","timezone": "America/Los_Angeles","timezone_offset": "-07:00"},"now": {"text": "多云", //天氣現象文字"code": "4", //天氣現象代碼"temperature": "14", //溫度,單位為c攝氏度或f華氏度"feels_like": "14", //體感溫度,單位為c攝氏度或f華氏度"pressure": "1018", //氣壓,單位為mb百帕或in英寸"humidity": "76", //相對濕度,0~100,單位為百分比"visibility": "16.09", //能見度,單位為km公里或mi英里"wind_direction": "西北", //風向文字"wind_direction_degree": "340", //風向角度,范圍0~360,0為正北,90為正東,180為正南,270為正西"wind_speed": "8.05", //風速 , 單位為km/h公里每小時或mph英里每小時"wind_scale": "2", //風力等級,請參考:http://baike.baidu.com/view/465076.htm"clouds": "90", //云量 , 單位%,范圍0~100,天空被云覆蓋的百分比 #目前不支持中國城市#"dew_point": "-12" //露點溫度,請參考:http://baike.baidu.com/view/118348.htm #目前不支持中國城市#},"last_update": "2015-09-25T22:45:00-07:00" //數據更新時間(該城市的本地時間)}]} 三、ESP32獲取天氣信息這里我使用的是ESP-IDF環境,并且是通過 socket 的方式進行獲取
  1. socket 通信思路如下圖所示:
    ESP32 IDF 獲取天氣信息

    文章插圖
  2. 創建socket連接
    函數int socket(int domain, int type, int protocol)含義函數socket()為通信創建一個端點,并為該套接字返回一個文件描述符 。返回值int,若發生錯誤則返回-1domain表示需要創建的協議 。如:AF_INET表示IPv4,AF_INET6表示IPv6 , AF_UNIX表示本地套接字type創建時,選擇需要的通行方式,如:SOCK_STREAM表示TCP,SOCK_DGRAM表示UDP,SOCK_SEQPACKET表示可靠的順序包服務,SOCK_RAW表示網絡層上的原始協議protocol表示指定要使用的實際傳輸協議最常見的有IPPROTO_TCP, IPPROTO_SCTP, IPPROTO_UDP, IPPROTO_DCCP等 。如果填0(IPPRORO_IP)則根據前兩個參數自動選擇協議/* 創建套接字 */socket_handle = socket(dns_info->ai_family, dns_info->ai_socktype, 0); // 0(IPPROTO_IP)可以用來表示選擇一個默認的協議 。if(socket_handle < 0) {ESP_LOGE(TAG, "... Failed to allocate socket");close(socket_handle);freeaddrinfo(dns_info);false;}
  3. 連接 connect連接時需要用到服務器的信息 , 而獲取天氣信息是通過域名的方式獲取的,在連接之前,我們需要使用getaddrinfo()函數進行DNS解析
    /* 域名解析 */int err = getaddrinfo(WEB_SERVER, WEB_PORT, &hints, &dns_info);if(err != 0 || dns_info == NULL) {ESP_LOGE(TAG, "DNS lookup failed err=%d dns_info=%p", err, dns_info);return false;}/* 連接服務器 */if(connect(socket_handle, dns_info->ai_addr, dns_info->ai_addrlen) != 0) {ESP_LOGE(TAG, "... socket connect failed errno=%d", errno);close(socket_handle);freeaddrinfo(dns_info);false;}
  4. 通過寫數據,發送get請求
    /* 想緩沖區中寫入服務請求信息 */if (write(socket_handle, REQUEST, strlen(REQUEST)) < 0) {ESP_LOGE(TAG, "... socket send failed");close(socket_handle);false;}

    推薦閱讀