Skip to content

IP电子围栏:设备离开指定区域自动告警

"电子围栏"这个词听着很高大上,其实在共享设备、物联网、资产管理这些场景里,用IP定位就能做一个低成本版本:设备换了个城市,自动告警。

这篇讲讲思路和代码。核心原理不复杂:定时查设备IP归属地,跟"设备应在的城市"对比,不一致就报警。

什么时候需要这东西

  • 共享充电宝/共享单车:设备被搬去别的城市了;
  • 企业资产:笔记本电脑、服务器离开指定区域;
  • 物联网设备:传感器、车载终端位置漂移监控;
  • 门禁/考勤:员工在公司网络外登录办公系统。

这些场景的共同点:设备没有GPS(或不想用GPS),但想知道它"大概在不在应该待的地方"。

核心逻辑

python
import requests
import time

def check_device(device_id, ip, expected_city):
    r = requests.get(f"https://ip9.com.cn/get?ip={ip}", timeout=3)
    d = r.json()
    if d.get("ret") != 200:
        return "unknown"      # 查不到,标记待确认
    info = d["data"]
    city = info.get("city") or info.get("prov")
    if city == expected_city:
        return "ok"
    # 城市变了 -> 告警
    alert(device_id, f"设备离开预期区域: {city}")
    return "moved"

expected_city 就是设备登记的"应在地"。每次设备上报IP,就查一次对比。

注意:别一有偏差就报警

这是电子围栏最容易做砸的地方。IP定位的精度是"城市级",边界情况很多:

  • 设备在城市交界处,IP可能在隔壁城市显示;
  • 运营商网络原因,IP短暂跳变;
  • 动态IP本来就会变。

所以正确做法是**"阈值 + 容忍"**:

python
def check_with_tolerance(device_id, ip, expected_city, history):
    city = query_city(ip)
    # 记录最近N次
    history[device_id].append(city)
    history[device_id] = history[device_id][-5:]
    # 最近5次里有3次以上都偏离 -> 才告警
    if sum(1 for c in history[device_id] if c != expected_city) >= 3:
        alert(device_id, f"设备已离开 {expected_city}")
        return True
    return False

"连续多次都偏移"才告警,能过滤掉大部分误报。

更精细:按省份判断 + 距离

如果设备是"跨省才算异常",就用 prov 判断;如果设备不能离得太远,可以用 lng/lat 算一下"设备城市中心"和"应在地城市中心"的距离:

python
import math

def city_distance(lat1, lng1, lat2, lng2):
    R = 6371
    p1, p2 = math.radians(lat1), math.radians(lat2)
    dp = p2 - p1
    dl = math.radians(lng2 - lng1)
    a = math.sin(dp/2)**2 + math.cos(p1)*math.cos(p2)*math.sin(dl/2)**2
    return 2 * R * math.asin(math.sqrt(a))

# 若设备应在地与当前IP城市中心距离超过阈值,则告警
if city_distance(dc_lat, dc_lng, ip_lat, ip_lng) > 200:  # 超过200公里
    alert(...)

注意这只是"城市中心到城市中心"的距离,别拿它当设备真实移动距离。

告警渠道

告警发到哪?几种常见选择:

  • 钉钉/企业微信/飞书机器人 webhook(最快);
  • 邮件(低频场景够用);
  • 短信(高优先级才用,有成本)。
python
def alert(device_id, msg):
    # 钉钉机器人示例
    webhook = "https://oapi.dingtalk.com/robot/send?access_token=xxx"
    requests.post(webhook, json={
        "msgtype": "text",
        "text": {"content": f"[设备告警] {device_id}: {msg}"}
    })

一个完整的巡检

可以用定时任务,每分钟把"在线设备"的IP批量查一遍(复用我"Python批量查询"那篇的脚本):

python
def patrol(devices):
    for dev in devices:
        if dev.is_online:
            check_with_tolerance(dev.id, dev.ip, dev.expected_city, history)

批量查询记得去重+缓存,别把接口打到限流。

说点实在的

IP电子围栏的精度就是"城市级到省市级",它能帮你发现"设备被搬到另一个城市"这种大动作,发现不了"设备挪了个小区"。明确它能干的事,别指望它干精确到米的活,那得靠GPS。

对共享设备、资产盘点这类"看大方向"的场景,这套已经够用了。

免费接口:https://www.ip9.com.cn