收藏官网首页
查看: 4883|回复: 0

[问答] 嵌入式设备如何显示IP属地?

99

主题

123

帖子

1695

积分

金牌会员

Rank: 6Rank: 6

积分
1695
跳转到指定楼层
楼主
 楼主| 发表于 2022-11-22 20:21:46 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
校园创客福利
本帖最后由 Cherry 于 2022-11-22 20:26 编辑

对于嵌入式物联网设备,除了一些特殊场合,比如环境监测、路径规划、定位追踪等,需要通过GPS模块获取精确的地理位置,对于一些天气预报、疫情数据相关的设备来说,地理位置要求没那么精确,只需要基本的时区、国家、城市/省份信息即可。

本文介绍,如何基于已有的WiFi/4G/5G联网功能,添加一个自动获取IP属地功能。共分为以下三个步骤:
  • 接口获取
  • 接口访问
  • JSON数据解析

1.获取API接口
IP定位需要使用公网IP,比如123.105.127.111,而不能是局域网IP,比如192.169.1.100。常用的IP定位接口有两种:
  • 一种是不需要知道当前设备的IP地址,直接访问接口,接口会返回设备的IP地址。
  • 一种是已知设备的IP地址,在访问接口时传入IP地址参数,接口会返回传入IP地址的经纬度、时区、国家、省份、城市等信息。

还有的是将以上两种接口整合为一个,无需事先知道设备的IP地址,直接使用设备访问接口,就会返回公网IP、经纬度、时区、国家、城市等信息。这里推荐一个免费的API接口:
  1. 程服务器地址: 103.205.5.249
  2. 远程服务器端口号: 80
  3. API接口: http://api.k780.com/?app=ip.local&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json
复制代码


返回的JSON数据:
  1. {
  2.     "success": "1",
  3.     "result": {
  4.         "ip": "102.212.134.15",
  5.         "proxy": "1",
  6.         "att": "中国,北京",
  7.         "operators": "联通"
  8.     }
  9. }
复制代码



先用网络调试助手测试一下:




API接口没问题,下一步使用嵌入式设备来完成自动获取IP地址。


2.嵌入式访问接口
联网模块主要有WiFi或移动网络4G模块,这里以比较常用的esp8266 WiFi模块+STM32为例,来演示通过串口AT指令来访问IP定位接口,下面是我使用STM32配置ESP8266的过程:


3.JSON数据解析
嵌入式设备可以使用的JSON解析库,常用的JSON解析库有cJSON和Jansson等。我之前也写过几篇关于JSON数据格式和JSON解析的文章,本文就不详细介绍了。
  • JSON数据格式简介
  • 使用cJSON库解析和构建json
  • Qt平台下QJson使用


如果你觉得使用解析库会额外的增加程序大小,你也可以使用字符串操作的一些函数,从返回的JSON字符串中提取出你想要的数据,这样会节省一部分微控制器的ROM空间。下面直接给出基于cJSON库,对以上IP定位接口返回数据进行解析的函数:

  1. #include "cJSON.h"

  2. uint8_t parse_api_data(char *jsonstr)
  3. {
  4.     cJSON *root;
  5.     cJSON *result;

  6.     char *ip;
  7.     char *loc;
  8.     char *net;

  9. //    printf("recv data: %d-%s\r\r\n", strlen((const char*)jsonstr), jsonstr);    //JSON原始数据
  10.     root = cJSON_Parse((const char*)USART2_RX_BUF);

  11.     if (root != 0)
  12.     {
  13.         printf("---JSON format ok---\r\n");
  14.         result = cJSON_GetObjectItem(root, "result");
  15.         ip = cJSON_GetObjectItem(result, "ip")->valuestring;        //164.123.44.15
  16.         loc = cJSON_GetObjectItem(result, "att")->valuestring;      //中国,北京
  17.         net = cJSON_GetObjectItem(result, "operators")->valuestring;//联通
  18.         printf("ip:%s\r\nloc:%s\r\nnet:%s\r\n", ip, loc, net);
  19.     }
  20.     else
  21.     {
  22.         printf("JSON format error:%s\r\n", cJSON_GetErrorPtr()); //输出json格式错误信息
  23.         return 1;
  24.     }
  25.     cJSON_Delete(root);

  26.     return 0;
  27. }
复制代码

4.商用API接口
还有一些其他的免费接口:
  1. /* 返回IP地址,地区、时序、国家等信息,默认是英文的 */
  2. http://ip-api.com/json/

  3. /* 可选中文 */
  4. http://ip-api.com/json/?lang=zh-CN

  5. /* SOHU接口,非标准JSON */
  6. http://pv.sohu.com/cityjson

  7. /* 国内的PCOnline提供的接口,定位不准确 */
  8. http://whois.pconline.com.cn/ipJson.jsp?json=true&ip=14.16.139.216

  9. /* 国外geoplugin公司提供的接口,包括经纬度、时区、货币单位、对美元汇率等信息 */
  10. http://www.geoplugin.net/json.gp
复制代码

以上免费接口都有随时关停的可能,如果用于商业用途,建议还是选择第三方商业公司提供的接口,或者自己开发API接口。本文推荐使用三大地图提供商的IP定位服务,一般支持自动定位,或查询指定IP地址对应的地址,返回信息一般包括国家,省份/城市,行政区划代码,经纬度等信息,数据格式一般支持JSON或XML,请求方式为GET或POST,可以进入官方网站查看详细的API文档,根据需求来选择:
  • 腾讯位置服务
https://lbs.qq.com/service/webService/webServiceGuide/webServiceIp
  • 百度地图开放平台
百度地图接口分为两个:普通IP定位和智能硬件定位,可以利用蓝牙、WI-FI、基站、GPS等信息,获取定位信息。https://lbsyun.baidu.com/index.php?title=webapi/intel-hardware-apihttps://lbsyun.baidu.com/index.php?title=webapi/ip-api
  • 高德开放平台
https://lbs.amap.com/api/webservice/guide/api/ipconfig如果对于访问次数和访问流量要求不高的话,只需要认证个人开发者/企业用户,就可以免费使用。



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

本版积分规则

加入Q群 返回顶部

版权与免责声明 © 2006-2024 Gizwits IoT Technology Co., Ltd. ( 粤ICP备11090211号 )

快速回复 返回顶部 返回列表