精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

【HarmonyOS HiSpark Wi-Fi IoT 套件試用連載】七、獲取網絡天氣數據

開發板試用精選 ? 來源:開發板試用 ? 作者:電子發燒友論壇 ? 2022-11-02 14:49 ? 次閱讀

本文來源電子發燒友社區,作者:李元江, 帖子地址:https://bbs.elecfans.com/jishu_2025428_1_1.html

元旦好冷,哪也不想去,那就趁著有空,寫寫帖子吧。今天的帖子我寫的是關于如何從網絡獲取天氣數據,以及如何解析出我們需要的天氣數據。

一、天氣數據獲取
首先說說怎么獲取天氣數據?,F在可以從很多平臺獲取到天氣數據,我使用的平臺是心知天氣,如何只是獲取實時天氣情況和最近幾天天氣情況是免費的,只要注冊賬號就可以使用。地址為:https://www.seniverse.com/。心知天氣里面不僅支持天氣數據獲取,還支持其他數據獲取。這里我們需要獲取天氣實況和逐日天氣情況。每個API有一個請求示例地址,逐日天氣請求示例地址如下,每個參數都會有相關說明。
213542d4cqq9z0511mcq92.jpg
在瀏覽器地址欄輸入請求示例地址后,可以查看返回數據內容情況。
213610apvffl1vt26u6vka.jpg
有了這個數據獲取接口,接下來以下步驟來獲取數據。
  • 連接心知天氣服務器心知天氣服務器地址為116.62.81.138。端口號為80,連接方式為TCP
  • 發送Get請求成功連接到心知天氣服務器后,需要發送Get請求才能獲取到數據。我要獲取最近三天的天氣預報情況,請求地址為https://api.seniverse.com/v3/weather/daily.json?key=SgJs9V9ghopE5WSBe&location=shenzhen&language=zh-Hans&unit=c&start=0&days=3則我們需要發送的數據為“Get https://api.seniverse.com/v3/weather/daily.json?key=SgJs9V9ghopE5WSBe&location=shenzhen&language=zh-Hans&unit=c&start=0&days=3rnrn”注意:最后為兩個回車換行。之后會返回天氣數據包,但是該數據包是Json格式的數據,需要解析才能得到我們真正需要的數據。下面是我使用調試助手獲取到的數據情況。

213934ognro1mzzmugg628.jpg

二、軟件設計
1、添加cJson功能

從網絡上直接獲取到的天氣數據是Json格式的,需要進行解析才能得到所需天氣數據。解析Json格式數據我借助第三方軟件包cJson,通過cJson解析出數據。其實在wifiiot的例程源代碼中,已經添加有cJson了。

213736xc9hmxw9n5is5iss.jpg

但是要使用cJson功能,還需要下面操作。在OLED下的BUILD.gn文件中include_dirs加入 "http://third_party/cJSON",

213757i99pvk9ogwoz4tvp.jpg

2、Json數據解析

在OLED下面新建從cjsonparse.c和cjsonparse.h文件,主要是關于Json數據解析的函數。這里我們獲取得天氣數據有兩個:實時天氣情況和未來三天天氣數據情況,所以需要解析實時天氣Json數據和未來三天天氣Json數據。

解析實時天氣,主要是為了獲取現在的溫度和天氣情況代碼。

  1. int cJSON_NowWeatherParse(char *JSON,weather *Weather)
  2. {
  3. cJSON *json,*arrayItem,*object,*subobject,*item;
  4. ?
  5. json = cJSON_Parse(JSON); //解析JSON數據包
  6. if(json == NULL) //檢測JSON數據包是否存在語法上的錯誤,返回NULL表示數據包無效
  7. {
  8. printf("Error before: [%s]n",cJSON_GetErrorPtr()); //打印數據包語法錯誤的位置
  9. return 1;
  10. }
  11. else
  12. {
  13. if((arrayItem = cJSON_GetObjectItem(json,"results")) != NULL) //匹配字符串"results",獲取數組內容
  14. {
  15. cJSON_GetArraySize(arrayItem); //獲取數組中對象個數
  16. //printf("cJSON_GetArraySize: size=%dn",size);
  17. if((object = cJSON_GetArrayItem(arrayItem,0)) != NULL)//獲取父對象內容
  18. {
  19. /* 匹配子對象1 */
  20. if((subobject = cJSON_GetObjectItem(object,"location")) != NULL)
  21. {
  22. ?
  23. }
  24. /* 匹配子對象2 */
  25. if((subobject = cJSON_GetObjectItem(object,"now")) != NULL)
  26. {
  27. printf("---------------------------------now-------------------------------n");
  28. //匹配子對象2成員"text"
  29. if((item = cJSON_GetObjectItem(subobject,"text")) != NULL)
  30. {
  31. printf("%s : %sn",item->string,item->valuestring);
  32. }
  33. //匹配子對象2成員"code"
  34. if((item = cJSON_GetObjectItem(subobject,"code")) != NULL)
  35. {
  36. printf("%s : %sn",item->string,item->valuestring);
  37. Weather->nowcode = str2int(item->valuestring);
  38. }
  39. //匹配子對象2成員"temperature"
  40. if((item = cJSON_GetObjectItem(subobject,"temperature")) != NULL)
  41. {
  42. printf("%s : %sn",item->string,item->valuestring);
  43. Weather->nowtemp = str2int(item->valuestring);
  44. }
  45. }
  46. /* 匹配子對象last_update */
  47. if((subobject = cJSON_GetObjectItem(object,"last_update")) != NULL)
  48. {
  49. printf("----------------------------last_update----------------------------n");
  50. printf("%s : %snn",subobject->string,subobject->valuestring);
  51. }
  52. }
  53. }
  54. }
  55. cJSON_Delete(json); //釋放cJSON_Parse()分配出來的內存空間
  56. return 0;
  57. }
復制代碼

解析未來三天天氣情況數據,主要為了獲取今天、明天、后天的最高、最低溫度、天氣情況代碼、濕度情況。當然也可以解析獲取更改天氣情況數據,但是這里我只解析獲取那么多。

  1. //解析三天天氣
  2. int cJSON_TayWeatherParse(char *JSON,weather *weather)
  3. {
  4. cJSON *root;
  5. cJSON *pSub;
  6. cJSON *arrayItem;
  7. cJSON *pItem;
  8. cJSON *pSubItem;
  9. cJSON *pChildItem;
  10. cJSON *pLastItem;
  11. char *pr;
  12. root = cJSON_Parse((const char*)JSON);
  13. if(root != NULL)
  14. {
  15. pSub = cJSON_GetObjectItem(root,"results");
  16. if(pSub != NULL)
  17. {
  18. arrayItem = cJSON_GetArrayItem(pSub,0);
  19. pr = cJSON_Print(arrayItem);
  20. pItem = cJSON_Parse(pr);
  21. if(pItem != NULL)
  22. {
  23. pSubItem = cJSON_GetObjectItem(pItem,"daily");
  24. if(pSubItem != NULL)
  25. {
  26. int size = cJSON_GetArraySize(pSubItem);
  27. for(int i=0;i;i++)
  28. {
  29. if(i==3)break;
  30. arrayItem = cJSON_GetArrayItem(pSubItem,i);
  31. pr = cJSON_Print(arrayItem);
  32. pLastItem = cJSON_Parse(pr);
  33. if(pLastItem != NULL)
  34. {
  35. if((pChildItem =cJSON_GetObjectItem(pLastItem,"high")) != NULL)
  36. {
  37. printf("%s : %sn",pChildItem->string,pChildItem->valuestring);
  38. weather->high[i] = str2int(pChildItem->valuestring);
  39. }
  40. ?
  41. if((pChildItem =cJSON_GetObjectItem(pLastItem,"low")) != NULL)
  42. {
  43. printf("%s : %sn",pChildItem->string,pChildItem->valuestring);
  44. weather->low[i] = str2int(pChildItem->valuestring);
  45. }
  46. if((pChildItem =cJSON_GetObjectItem(pLastItem,"code_day"))!=NULL)
  47. {
  48. printf("%s : %sn",pChildItem->string,pChildItem->valuestring);
  49. weather->code[i] = str2int(pChildItem->valuestring);
  50. }
  51. if((pChildItem =cJSON_GetObjectItem(pLastItem,"humidity"))!=NULL)
  52. {
  53. printf("%s : %sn",pChildItem->string,pChildItem->valuestring);
  54. weather->humi[i] = str2int(pChildItem->valuestring);
  55. }
  56. }
  57. cJSON_Delete(pLastItem);
  58. }
  59. }
  60. }
  61. cJSON_Delete(pItem);
  62. }
  63. }
  64. cJSON_Delete(root);
  65. ?
  66. return 0;
  67. }
復制代碼
3、 獲取天氣數據

新建getweather.c文件,主要獲取天氣數據的功能函數。設置的代碼中主要經過如下步驟獲取和解析天氣情況數據。

  • 1、連接網絡
  • 2、 連接到服務器
  • 3、發送近三天天氣情況請求
  • 4、接收數據
  • 5、解析近三天天氣Json數據
  • 6、關閉與服務器連接
  • 7、從新連接到服務器
  • 8、發送實時天氣情況請求
  • 9、接收數據
  • 10、解析實時天氣Json數據
  • 11、關閉與服務器連接
  • 12、斷開與網絡的連接
  1. #include
  2. #include
  3. #include
  4. #include
  5. ?
  6. #include "net_demo.h"
  7. #include "net_common.h"
  8. #include "net_params.h"
  9. #include "wifi_connecter.h"
  10. #include "ohos_init.h"
  11. #include "cmsis_os2.h"
  12. #include "cjsonparse.h"
  13. ?
  14. #define WEATHERIPADDR "116.62.81.138"
  15. #define WEATHERPORT 80
  16. ?
  17. static char requestday[] = "GET https://api.seniverse.com/v3/weather/daily.json?key=SgJs9V9ghopE5WSBe&location=shenzhen&language=zh-Hans&unit=c&start=0&days=3rnrn";
  18. static char requestnow[] = "GET https://api.seniverse.com/v3/weather/now.json?key=SgJs9V9ghopE5WSBe&location=shenzhen&language=zh-Hans&unit=crnrn";
  19. ?
  20. static char response[1000] = "";
  21. ?
  22. weather weatherValue;
  23. ?
  24. bool getWeather(void){
  25. bool sucflag = false;
  26. WifiDeviceConfig config = {0};
  27. ?
  28. // 準備AP的配置參數
  29. strcpy(config.ssid, PARAM_HOTSPOT_SSID);
  30. strcpy(config.preSharedKey, PARAM_HOTSPOT_PSK);
  31. config.securityType = PARAM_HOTSPOT_TYPE;
  32. osDelay(10);
  33. int netId = ConnectToHotspot(&config);
  34. ?
  35. /*獲取最近三天天氣情況*/
  36. int32_t retval = 0;
  37. int sockfd = socket(AF_INET, SOCK_STREAM, 0); // TCP socket
  38. struct sockaddr_in serverAddr = {0};
  39. serverAddr.sin_family = AF_INET;// AF_INET表示IPv4協議
  40. serverAddr.sin_port = htons(WEATHERPORT);// 端口號,從主機字節序轉為網絡字節序
  41. if (inet_pton(AF_INET, WEATHERIPADDR, &serverAddr.sin_addr) <= 0) {??// 將主機IP地址從“點分十進制”字符串 轉化為 標準格式(32位整數)
  42. printf("inet_pton failed!rn");
  43. goto do_cleanup;
  44. }
  45. // 嘗試和目標主機建立連接,連接成功會返回0 ,失敗返回 -1
  46. if (connect(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
  47. printf("connect failed!rn");
  48. goto do_cleanup;
  49. }
  50. printf("connect to server %s success!rn", WEATHERIPADDR);
  51. ?
  52. // 建立連接成功之后,這個TCP socket描述符 —— sockfd 就具有了 “連接狀態”,發送、接收 對端都是 connect 參數指定的目標主機和端口
  53. //retval = send(sockfd, requestnow, sizeof(requestnow), 0);
  54. retval = send(sockfd, requestday, sizeof(requestday), 0);
  55. if (retval < 0) {
  56. printf("send request failed!rn");
  57. goto do_cleanup;
  58. }
  59. printf("send request{%s} %ld to server done!rn", requestday, retval);
  60. retval = recv(sockfd, &response, sizeof(response), 0);
  61. if (retval <= 0) {
  62. printf("send response from server failed or done, %ld!rn", retval);
  63. goto do_cleanup;
  64. }
  65. response[retval] = '';
  66. int i = 0;
  67. /*打印接收到數據*/
  68. while(i)
  69. {
  70. printf("%c",response[i]);
  71. i++;
  72. }
  73. cJSON_TayWeatherParse(response,&weatherValue);
  74. close(sockfd);
  75. ?
  76. /*獲取現在的天氣情況*/
  77. sockfd = socket(AF_INET, SOCK_STREAM, 0); // TCP socket
  78. if (inet_pton(AF_INET, WEATHERIPADDR, &serverAddr.sin_addr) <= 0) {??// 將主機IP地址從“點分十進制”字符串 轉化為 標準格式(32位整數)
  79. printf("inet_pton failed!rn");
  80. goto do_cleanup;
  81. }
  82. // 嘗試和目標主機建立連接,連接成功會返回0 ,失敗返回 -1
  83. if (connect(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
  84. printf("connect failed!rn");
  85. goto do_cleanup;
  86. }
  87. ?
  88. retval = send(sockfd, requestnow, sizeof(requestnow), 0);
  89. if (retval < 0) {
  90. printf("send request failed!rn");
  91. goto do_cleanup;
  92. }
  93. printf("send request{%s} %ld to server done!rn", requestnow, retval);
  94. retval = recv(sockfd, &response, sizeof(response), 0);
  95. if (retval <= 0) {
  96. printf("send response from server failed or done, %ld!rn", retval);
  97. goto do_cleanup;
  98. }
  99. response[retval] = '';
  100. i = 0;
  101. /*打印接收到數據*/
  102. while(i)
  103. {
  104. printf("%c",response[i]);
  105. i++;
  106. }
  107. cJSON_NowWeatherParse(response,&weatherValue);
  108. sucflag=true;
  109. do_cleanup:
  110. close(sockfd);
  111. DisconnectWithHotspot(netId);
  112. if(sucflag)
  113. return true;
  114. else
  115. return false;
  116. }
復制代碼
4、加入任務中

把獲取天氣數據功能增加到任務中。在oled_demo.c中static void OledTask(void *arg)函數增加以下代碼。

  1. AdcRead(ANALOG_KEY_CHAN_NAME, &data, WIFI_IOT_ADC_EQU_MODEL_4, WIFI_IOT_ADC_CUR_BAIS_DEFAULT, 0);
  2. float voltage = ConvertToVoltage(data);
  3. ?
  4. if(voltage>0.45 && voltage<0.65)
  5. {
  6. OledShowString(16,7,"Sync time...",1);
  7. getNtpTime();
  8. OledFillScreen(0);
  9. }
  10. else if(voltage>0.9 && voltage<1)
  11. {
  12. ?
  13. OledShowString(0,7,"Get Weather...",1);
  14. if(getWeather())
  15. OledFillScreen(0);
  16. else
  17. {
  18. OledShowString(0,7,"Get fail...",1);
  19. }
  20. }
復制代碼

按下oled顯示板的右邊按鈕,會進入獲取天氣情況功能?,F在我這里只是通過串口打印出來的數據,觀察數據獲取和解析情況,還沒有把解析后的天氣數據顯示到oled上。

5、修改BUILD.gn

修改OLED文件夾下的BUILD.gn文件,sources中加入getweather.c和cjsonparse.c

  1. sources = [
  2. "oled_demo.c",
  3. "oled_ssd1306.c",
  4. "timeconv.c",
  5. "envrionment_demo.c",
  6. "aht20.c",
  7. "wifi_connecter.c",
  8. "getNTP.c",
  9. "getweather.c",
  10. "cjsonparse.c",
  11. ]
復制代碼

三、結果演示

按下OLED顯示板右邊按鍵,會進入天氣數據功能,之后顯示“Get Weather....”提示。天氣數據獲取失敗后,會顯示“Get fail...”提示。

214220iyvnrgrc8jq8y303.jpg

可以從串口打印輸出的信息,觀察到獲取的Json數據情況和解析后的數據情況。

213858izk35ikaklkzupe3.jpg


四、總結

網絡天氣數據的獲取主要經過如下步驟

  • 連接網絡
  • 連接服務器
  • 請求數據
  • 解析Json數據

2021年第一篇帖子,先寫到這里。下一篇是關于通過TCP連接與手機APP進行數據交互的帖子。當然手機APP是我之前做好的。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • wi-fi
    +關注

    關注

    14

    文章

    2112

    瀏覽量

    124330
  • HarmonyOS
    +關注

    關注

    79

    文章

    1967

    瀏覽量

    30025
  • HiSpark
    +關注

    關注

    1

    文章

    156

    瀏覽量

    6904
收藏 人收藏

    評論

    相關推薦

    Wi-Fi 8要來了!未來Wi-Fi技術演進方向揭秘

    電子發燒友網報道(文/梁浩斌)Wi-Fi 7芯片早在2022年就有產品推出,直到去年年底,Wi-Fi 7設備開始大量推出市場。但從普及率來看,根據奧維云網的數據,截至2024年9月,線上家用路由器
    的頭像 發表于 11-24 03:14 ?710次閱讀
    <b class='flag-5'>Wi-Fi</b> 8要來了!未來<b class='flag-5'>Wi-Fi</b>技術演進方向揭秘

    Wi-Fi 7與Wi-Fi 6E有什么區別

    也許很多人還在考慮是否要將使用的Wi-Fi設備升級到Wi-Fi 6或Wi-Fi 6E,而這些標準的繼任者卻已經開始“登堂入室”了。Wi-Fi 7是新一代
    的頭像 發表于 11-07 11:38 ?506次閱讀

    IR900 Wi-Fi聯網的配置過程

    例如上圖,IR900 通過Wi-Fi接口連接公司辦公無線網絡 inhand-office (SSID為無線網絡的名稱) 首先將Wi-Fi接口與WLAN接口解綁 登陸IR900后,進
    發表于 07-25 06:09

    AT 0.60.0.0看不到我的Wi-Fi網絡,為什么?

    我對 AT 0.60.0.0 有一點問題。當我通過 AT CWLAP 顯示所有網絡時,我看不到我的路由器 AP 網絡,但我可以連接到它。當我在智能手機中打開 Wi-Fi 熱點時,我可以看到我的熱點
    發表于 07-18 08:31

    DA16200 超低功耗 Wi-Fi 模塊開發套件 Pro數據手冊

    電子發燒友網站提供《DA16200 超低功耗 Wi-Fi 模塊開發套件 Pro數據手冊.rar》資料免費下載
    發表于 05-30 17:53 ?1次下載
    DA16200 超低功耗 <b class='flag-5'>Wi-Fi</b> 模塊開發<b class='flag-5'>套件</b> Pro<b class='flag-5'>數據</b>手冊

    DA16200 超低功耗 Wi-Fi 模塊開發套件數據手冊

    電子發燒友網站提供《DA16200 超低功耗 Wi-Fi 模塊開發套件數據手冊.rar》資料免費下載
    發表于 05-30 17:13 ?0次下載
    DA16200 超低功耗 <b class='flag-5'>Wi-Fi</b> 模塊開發<b class='flag-5'>套件數據</b>手冊

    華為獲得全球首個國際Wi-Fi聯盟WFA企業級Wi-Fi 7認證!

    Wi-Fi聯盟已發布Wi-Fi 7認證標準,華為是第一批送測廠商,獲得業界首個企業級Wi-Fi 7 的Wi-Fi聯盟官方認證。
    的頭像 發表于 04-28 10:17 ?650次閱讀
    華為獲得全球首個國際<b class='flag-5'>Wi-Fi</b>聯盟WFA企業級<b class='flag-5'>Wi-Fi</b> 7認證!

    驗證物聯網Wi-Fi HaLow用例的MM6108-EKH08開發套件來啦

    驗證物聯網Wi-Fi HaLow用例的MM6108-EKH08開發套件來啦 MM6108-EKH08開發套件專為驗證物聯網Wi-Fi HaLow用例而設計。該
    的頭像 發表于 04-11 12:01 ?1662次閱讀
    驗證物聯網<b class='flag-5'>Wi-Fi</b> HaLow用例的MM6108-EKH08開發<b class='flag-5'>套件</b>來啦

    Wi-Fi 7與Wi-Fi 6的相關知識科普

    科普:Wi-Fi 7 vs. Wi-Fi 6,青出于藍
    的頭像 發表于 03-12 10:59 ?692次閱讀
    <b class='flag-5'>Wi-Fi</b> 7與<b class='flag-5'>Wi-Fi</b> 6的相關知識科普

    Wi-Fi的誕生與發展

    和5GHz兩個頻段,承載著不斷增長的網絡需求。ABIResearch顯示,2022年Wi-Fi上傳流量激增80%,Wi-Fi數據流量已超過蜂窩流量,且成為流量增量貢
    的頭像 發表于 03-07 08:26 ?1136次閱讀
    <b class='flag-5'>Wi-Fi</b>的誕生與發展

    Wi-Fi HaLow和傳統Wi-Fi的區別

    Wi-Fi HaLow和傳統Wi-Fi的區別? Wi-Fi是一種無線網絡技術,可以連接到互聯網或局域網,為用戶提供無線上網的便利。隨著科技的發展和互聯網的普及,
    的頭像 發表于 02-02 15:28 ?1119次閱讀

    康普攜手Wi-Fi聯盟,RUCKUS Wi-Fi 7系列接入點成Wi-Fi

     康普高級副總裁兼網絡、智能蜂窩和安全解決方案總裁Bart Giordano對此表示: “我們非常榮幸能與Wi-Fi Alliance形成長期合作伙伴關系,將我們的RUCKUS Wi-Fi 7 接入點平臺作為
    的頭像 發表于 01-23 14:10 ?707次閱讀

    BT Wi-Fi模式是否可以通過ModustoolBox對套件進行編程來實現?

    想配置用于分析 CYW43439 的 CY8CPROTO-062S2-43439 原型開發套件。 瀏覽文檔我無法弄清楚如何在不同的 Wi-Fi 和藍牙模式(電源模式、連接模式等)下配置套件。 在
    發表于 01-22 06:19

    Wi-Fi聯盟已正式確認Wi-Fi 7標準,無線網絡新時代來臨!Wi-Fi 聯盟已開始對 Wi-Fi 7 設備

    無線網絡wi-fi
    北京中科同志科技股份有限公司
    發布于 :2024年01月10日 10:43:56

    Wi-Fi 6和Wi-Fi 5之間有哪些區別呢?

    Wi-Fi 6和Wi-Fi 5之間有哪些區別呢? Wi-Fi 6和Wi-Fi 5是無線局域網標準的兩個版本,它們之間存在很多區別。Wi-Fi
    的頭像 發表于 12-09 16:09 ?2241次閱讀