实验任务
作业题目7:实现在MSH命令行中,输入命令获取指定城市天气信息
PS:作业6暂时没法完成了,哭死,手上的ESP8266模块无法进行UDP通信,TCP都是正常的,哈哈哈,还好作业7是通过TCP进行的,美滋滋。
实验目的
熟悉心知天气的获取方式,熟悉cJson的格式数据的解析。
实验环境
1、硬件环境:野火STM32霸道开发板
2、软件环境:RT-Thread Nano 3.1.3,MDK 5.25
实验步骤
1、添加cJon软件包,这个应该不用多说了。实在不会的话,到RT-Thread的官网软件包中心去下载就行,我贴一个链接:cJson软件包
2、到心知天气官网注册账号,新增产品,查看天气数据时怎么获取的。官网也有很详细的介绍。其实有很多不清楚的东西,去他们的官网找资料肯定没错了。这里也贴一个链接:心知天气API文档
3、通过ESP8266获取心知天气的数据
也就是通过ESP8266连接到心知天气的服务器,然后发送下面这串数据,等待服务器返回的数据就行了 https://api.seniverse.com/v3/weather/now.json?key=你的私钥&location=你的城市\r\n\r\n
/* 心知天气(api.seniverse.com)--天气数据的来源 */
#define WEATHER_IP "116.62.81.138"
#define WEATHER_PORT "80"
/********************************************************************************************************
** 函数: GetNowWeather, GET 天气实况数据包now.json
**------------------------------------------------------------------------------------------------------
** 参数: void
** 说明: 数据来源:心知天气(api.seniverse.com)
** 返回: 0:获取成功 其他:获取失败
** 作者: 2017.12.8 by Hezhijie and Lizhengnian
********************************************************************************************************/
int GetNowWeather(int argc, char *argv[])
{
char cStr [256] = { 0 };
if( argc != 2 )
{
printf("Example : GetNowWeather shenzhen");
return 0;
}
sprintf ( cStr, "%s%s\r\n\r\n", "GET https://api.seniverse.com/v3/weather/now.json?key=改成你自己的私钥&location=", argv[1]);
printf("%s", cStr);
ESP8266_Link_Server(enumTCP, (char*)WEATHER_IP, (char*)WEATHER_PORT,Single_ID_0);//TCP
ESP8266_UnvarnishSend ();//传输模式为:透传
macESP8266_Usart ( cStr );//以福州天气为例子获取
strEsp8266_Fram_Record .InfBit .FramLength = 0; //重新开始接收新的数据包
rt_thread_mdelay(1000);
strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ] = '\0';
printf("Receive now data:%s\r\n",strEsp8266_Fram_Record .Data_RX_BUF);
cJSON_NowWeatherParse((char*)strEsp8266_Fram_Record .Data_RX_BUF, &weather_data);
ESP8266_ExitUnvarnishSend ( );//退出透传HZJ
ESP8266_Close_Link ( );//关闭TCP或UDP连接HZJ
return 0;
}
4、解析心知天气的数据
/********************************************************************************************************
** 函数: cJSON_NowWeatherParse, 解析天气实况数据包now.json
**------------------------------------------------------------------------------------------------------
** 参数: JSON:天气实况数据包 WeatherType:存储解析得到的有用的数据
** 说明: 数据来源:心知天气(api.seniverse.com)
** 返回: 0:解析成功 其他:解析失败
** 作者: 2017.12.6 by Hezhijie and Lizhengnian
********************************************************************************************************/
static int cJSON_NowWeatherParse(char *JSON, WeatherType *result)
{
cJSON *json,*arrayItem,*object,*subobject,*item;
//printf("Receive now data:%s\r\n",JSON);
json = cJSON_Parse(JSON);//解析JSON数据包
if(json == NULL) //检测JSON数据包是否存在语法上的错误,返回NULL表示数据包无效
{
printf("Error before: [%s]\r\n",cJSON_GetErrorPtr()); //打印数据包语法错误的位置
return 1;
}
else
{
if((arrayItem = cJSON_GetObjectItem(json,"results")) != NULL); //匹配字符串"results",获取数组内容
{
int size = cJSON_GetArraySize(arrayItem); //获取数组中对象个数
// printf("cJSON_GetArraySize: size=%d\n",size);
if((object = cJSON_GetArrayItem(arrayItem,0)) != NULL)//获取父对象内容
{
printf("--------------------------------Now Weather Data Begin------------------------------\r\n");
/* 匹配子对象1 */
if((subobject = cJSON_GetObjectItem(object,"location")) != NULL)
{
printf("---------------------------------subobject1-------------------------------\r\n");
if((item = cJSON_GetObjectItem(subobject,"id")) != NULL)
{
printf("cJSON_GetObjectItem: %s:%s\r\n",item->string,item->valuestring);
}
if((item = cJSON_GetObjectItem(subobject,"name")) != NULL) //地名--需要用到的数据
{
printf("cJSON_GetObjectItem: %s:%s\r\n",item->string,item->valuestring);
}
if((item = cJSON_GetObjectItem(subobject,"country")) != NULL)
{
printf("cJSON_GetObjectItem: %s:%s\r\n",item->string,item->valuestring);
}
if((item = cJSON_GetObjectItem(subobject,"path")) != NULL)
{
printf("cJSON_GetObjectItem: %s:%s\r\n",item->string,item->valuestring);
}
if((item = cJSON_GetObjectItem(subobject,"timezone")) != NULL)
{
printf("cJSON_GetObjectItem: %s:%s\r\n",item->string,item->valuestring);
}
if((item = cJSON_GetObjectItem(subobject,"timezone_offset")) != NULL)
{
printf("cJSON_GetObjectItem: %s:%s\r\n",item->string,item->valuestring);
}
}
/* 匹配子对象2 */
if((subobject = cJSON_GetObjectItem(object,"now")) != NULL)
{
printf("---------------------------------subobject2-------------------------------\r\n");
if((item = cJSON_GetObjectItem(subobject,"text")) != NULL)//天气预报文字--需要用到的数据
{
printf("cJSON_GetObjectItem: %s:%s\r\n",item->string,item->valuestring);
}
if((item = cJSON_GetObjectItem(subobject,"code")) != NULL)//天气预报代码--需要用到的数据
{
printf("cJSON_GetObjectItem: %s:%s\r\n",item->string, item->valuestring);
}
if((item = cJSON_GetObjectItem(subobject,"temperature")) != NULL) //温度--需要用到的数据
{
printf("cJSON_GetObjectItem: %s:%s\r\n",item->string, item->valuestring);
}
}
/* 匹配子对象3 */
if((subobject = cJSON_GetObjectItem(object,"last_update")) != NULL)
{
printf("---------------------------------subobject3-------------------------------\r\n");
printf("cJSON_GetObjectItem: %s:%s\r\n",subobject->string,subobject->valuestring);
}
printf("--------------------------------Now Weather Data End--------------------------------\r\n");
}
}
}
cJSON_Delete(json); //释放cJSON_Parse()分配出来的内存空间
return 0;
}
测试结果
在终端中输入GetNowWeather shenzhen 表示获取深圳的实时天气,返回如下数据,也就成功了。