1863|7

282

帖子

2

TA的资源

一粒金砂(高级)

楼主
 

【智能网络台灯】7. 获取实时天气信息并解析 [复制链接]

 

过往分享

【2022得捷电子创新设计大赛】最晚开箱帖
【2022得捷电子创新设计大赛】1. ESP32-S2环境搭建及点灯
【智能网络台灯】2. 设置系统时间以及打印
【智能网络台灯】3. ESP32-S2 + lvgl使用
【智能网络台灯】4. ESP32-S2 板载按键使用
【智能网络台灯】5. ESP32-S2 使用sntp进行网络校时
【智能网络台灯】6. ESP32-S2解决RAM空间开销过大的问题

前言

准备给我的智能台灯加上天气的功能,本帖分享一下添加该功能的过程。

天气功能使用的是https来获取的http://www.yiketianqi.com的API,该网站提供免费的实时天气API以及七日天气API,本文只使用了实时天气,免费用户每日可获取500次。
网址如下:https://www.yiketianqi.com/index/doc?version=day

添加https功能

参考了官方例程https_request:Espressif\frameworks\esp-idf-v4.4\examples\protocols\https_request

然后根据实际情况进行了修改。
修改如下:

  1. #define WEB_WEA_SERVER "v0.yiketianqi.com"
  2. #define WEB_PORT "443"
  3. #define WEB_WEA_HTTPS_URL "https://v0.yiketianqi.com"
  4. // 获取实时天气的地址
  5. #define WEB_WEA_ONE_URL "/free/day?appid=自己的id&appsecret=自己的secret&unescape=1"
  6. // https请求
  7. static const char REQUEST[] = "GET " WEB_WEA_ONE_URL " HTTP/1.0\r\n"
  8. "Host: "WEB_WEA_SERVER ":" WEB_PORT "\r\n"
  9. "User-Agent: esp-idf/1.0 esp32\r\n"
  10. "\r\n";
  11. // https请求天气信息
  12. static void https_get_request(void)
  13. {
  14. char buf[512];
  15. int ret, len;
  16. size_t written_bytes = 0;
  17. char weather_info[512];
  18. uint16_t weather_cnt = 0;
  19. struct esp_tls *tls;
  20. // https get请求,使用crt bundle方式
  21. ESP_LOGI(TAG, "https_request using crt bundle");
  22. esp_tls_cfg_t cfg = {
  23. .crt_bundle_attach = esp_crt_bundle_attach,
  24. };
  25. tls = esp_tls_conn_http_new(WEB_WEA_HTTPS_URL, &cfg);
  26. if (tls != NULL)
  27. {
  28. ESP_LOGI(TAG, "Connection established...");
  29. }
  30. else
  31. {
  32. ESP_LOGE(TAG, "Connection failed...");
  33. goto exit;
  34. }
  35. do
  36. {
  37. ret = esp_tls_conn_write(tls,
  38. REQUEST + written_bytes,
  39. sizeof(REQUEST) - written_bytes);
  40. if (ret >= 0)
  41. {
  42. ESP_LOGI(TAG, "%d bytes written", ret);
  43. written_bytes += ret;
  44. }
  45. else if (ret != ESP_TLS_ERR_SSL_WANT_READ && ret != ESP_TLS_ERR_SSL_WANT_WRITE)
  46. {
  47. ESP_LOGE(TAG, "esp_tls_conn_write returned: [0x%02X](%s)", ret, esp_err_to_name(ret));
  48. goto exit;
  49. }
  50. } while (written_bytes < sizeof(REQUEST));
  51. ESP_LOGI(TAG, "Reading HTTP response...");
  52. do
  53. {
  54. len = sizeof(buf) - 1;
  55. bzero(buf, sizeof(buf));
  56. ret = esp_tls_conn_read(tls, (char *)buf, len);
  57. if (ret == ESP_TLS_ERR_SSL_WANT_WRITE || ret == ESP_TLS_ERR_SSL_WANT_READ)
  58. {
  59. continue;
  60. }
  61. if (ret < 0)
  62. {
  63. ESP_LOGE(TAG, "esp_tls_conn_read returned [-0x%02X](%s)", -ret, esp_err_to_name(ret));
  64. break;
  65. }
  66. else if (ret == 0)
  67. {
  68. ESP_LOGI(TAG, "connection closed");
  69. break;
  70. }
  71. len = ret;
  72. ESP_LOGD(TAG, "%d bytes read", len);
  73. /* Print response directly to stdout as it is read */
  74. for (int i = 0; i < len; i++)
  75. {
  76. putchar(buf<i>);
  77. // 获取天气部分数据到buffer 'weather_info', 其他信息摒除
  78. if ((buf<i> == '{') || (weather_cnt > 0U))
  79. {
  80. weather_info[weather_cnt++] = buf<i>;
  81. }
  82. }
  83. putchar('\n'); // JSON output doesn't have a newline at end
  84. } while (1);
  85. // 添加字符串结束符
  86. weather_info[weather_cnt] = '\0';
  87. ESP_LOGD(TAG, "Weather Info: %s", weather_info);
  88. Weather_InfoParse(weather_info);
  89. exit:
  90. weather_cnt = 0;
  91. esp_tls_conn_delete(tls);
  92. }
  93. // 获取天气信息请求
  94. static void Weather_HttpsRequest(void)
  95. {
  96. https_get_request();
  97. }
  98. // 解析天气数据
  99. static void Weather_InfoParse(char *json_data)
  100. {
  101. cJSON* root = cJSON_Parse(json_data);;
  102. cJSON* cjson_item = cJSON_GetObjectItem(root, "wea");
  103. cJSON* cjson_temp_curr = cJSON_GetObjectItem(root, "tem");
  104. cJSON* cjson_temp_high = cJSON_GetObjectItem(root, "tem_day");
  105. cJSON* cjson_temp_low = cJSON_GetObjectItem(root, "tem_night");
  106. cJSON* cjson_air = cJSON_GetObjectItem(root, "air");
  107. cJSON* cjson_pressure = cJSON_GetObjectItem(root, "pressure");
  108. cJSON* cjson_humi = cJSON_GetObjectItem(root, "humidity");
  109. printf("当前天气:%s\n", cjson_item->valuestring);
  110. printf("当前温度:%s\n", cjson_temp_curr->valuestring);
  111. printf("最高温度weather:%s\n", cjson_temp_high->valuestring);
  112. printf("最低温度:%s\n", cjson_temp_low->valuestring);
  113. printf("空气质量:%s\n", cjson_air->valuestring);
  114. printf("大气压强:%s\n", cjson_pressure->valuestring);
  115. printf("当前湿度:%s\n", cjson_humi->valuestring);
  116. }

注意事项

如上,需要注意的几点说一下:

  1. 例程中使用的是https/1.1,这种方式虽然也能获取天气,但是会返回400 bad request,修改为https/1.0可以解决,报错信息如下:

修改如下:

改后效果:

  1. 文件编码不对,导致串口打印出来是乱码,修改文件编码,在IDE中修改很方便,如下图,修改为UTF-8,只需要修改运行改代码的文件即可。
  1. 就算修改了,使用串口打印还有可能是乱码,找一个支持utf-8的串口调试助手,推荐putty,可以解决这个问题,如下图:

最新回复

非常有用,谢谢分享   详情 回复 发表于 2022-9-15 13:41
点赞 关注
 
 

回复
举报

6909

帖子

10

TA的资源

版主

沙发
 

天气地址信息是本地的还是网络的,这是一个公共信息网吗?

 
 
 

回复

7545

帖子

2

TA的资源

版主

板凳
 

后面是不是就准备把数据显示到屏幕上了?

点评

是的,准备这么做了  详情 回复 发表于 2022-9-13 20:48
 
 
 

回复

282

帖子

2

TA的资源

一粒金砂(高级)

4
 
秦天qintian0303 发表于 2022-9-13 08:59 天气地址信息是本地的还是网络的,这是一个公共信息网吗?

是获取的网络天气,就这个网址:https://www.yiketianqi.com/index/doc?version=day

免费用户每天可以获取500次,够用了

点评

解析JSON可以加一些判断,要是能能成彩色的就好啦  详情 回复 发表于 2022-9-14 22:38
 
 
 

回复

282

帖子

2

TA的资源

一粒金砂(高级)

5
 
wangerxian 发表于 2022-9-13 09:16 后面是不是就准备把数据显示到屏幕上了?

是的,准备这么做了

点评

期待ing~  详情 回复 发表于 2022-9-14 09:53
 
 
 

回复

7545

帖子

2

TA的资源

版主

6
 
hehung 发表于 2022-9-13 20:48 是的,准备这么做了

期待ing~

 
 
 

回复

5029

帖子

12

TA的资源

版主

7
 
hehung 发表于 2022-9-13 20:48 是获取的网络天气,就这个网址:https://www.yiketianqi.com/index/doc?version=day, 免费用户每天可 ...

解析JSON可以加一些判断,要是能能成彩色的就好啦

 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

8
 

非常有用,谢谢分享

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
有奖直播:当AI遇见仿真,会有什么样的电子行业革新之路?
首场直播:Simcenter AI 赋能电子行业研发创新
直播时间:04月15日14:00-14:50

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 6

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表