1.项目来源

余尝行于山野,犬忽逸去。初日遍寻不获,中心焦灼。翌日,途人传信云:“道旁见一犬,状似尔家。”急趋视之,果是,遂携归。因思防患未然,乃决为犬佩卫星定位之器。其器所求者三:一曰形微,不累犬行;二曰蓄电力久,可历旬日;三曰能遥制启闭——平居则令入静默之态,需时瞬息可醒。

2.设备选型

1.定位模块:Air780e合宙4G通信模块核心板

2.电池:聚合物锂电池芯3.7V
3.磁吸充电座:磁吸公母头带PCB有孔定固
4.外壳:3D打印

3.模块参数设置

开启远程控制命令


设置为MQTT通信,其他参数自行配置

4.服务器搭建

4.1总体通信流程

4.2MQTT服务器搭建

4.3网页服务器搭建

4.3.1 项目概述与最终功能

本项目旨在通过部署在本地服务器(如 Debian/树莓派)上的 Flask Web 应用,实时接收 4G DTU 设备通过 MQTT 透传的 GPS/LBS 位置数据,并在网页地图上直观显示设备的当前位置和历史轨迹。

核心功能列表

类别 功能描述 实现方法
数据持久化 SQLite 数据库存储:替换文件存储,实现高效的每日轨迹记录和零点自动刷新。 后端 app.py 集成 sqlite3 模块。
安全与访问 登录身份验证:强制用户通过密码登录才能访问地图页面和 API,保障数据隐私。 Flask session 管理登录状态。
定位与校准 高德地图坐标修正:前端采用 WGS84 到 GCJ02 坐标转换算法,确保位置在高德地图上准确显示。 前端 JavaScript 实现坐标转换。
DTU 状态 实时状态查询:顶部状态栏显示 DTU 状态,可手动刷新。 后端解析 config,csq,ok, config,ssta,ok 等文本回执。
设备控制 精细化设置:通过页面操作实现 GPS/LBS 上报周期、低功耗模式、日志开关等远程配置。 前后端封装 DTU 的 config,set 指令。
地图优化 图层与轨迹控制:增加卫星/标准地图切换开关和轨迹路径显示开关。 Leaflet API 实现图层管理。
状态持久化 配置回显:设备上报参数(GPS/LBS 开关状态和周期)持久化存储,网页刷新后保持显示。 后端 sys_config.json 文件。

4.3.2 系统架构与部署结构

本项目采用前后端分离、MQTT 异步通信的轻量级架构。

架构图

核心文件结构

gps_tracker/
├── app.py                  # 后端 Flask 应用, MQTT通信, SQLite逻辑, 身份验证
├── tracker.db              # SQLite 数据库文件 (运行时自动生成,存储轨迹)
├── sys_config.json         # 配置文件 (运行时自动生成,存储GPS/LBS开关状态)
├── templates/
│   ├── index.html          # 主界面:地图、状态显示、控制面板 (前端JS逻辑)
│   └── login.html          # 登录验证界面
└── requirements.txt        # 依赖包列表

部署环境 (Prerequisites)

  • 操作系统: Debian, Ubuntu 或任何支持 Python 的 Linux 系统 (推荐使用 venv 虚拟环境)。

  • Python: Python 3.x

  • MQTT: 需部署 MQTT Broker (如 Mosquitto) 并确保 DTU 能连接上。

  • Python 依赖:

    pip install Flask Flask-SocketIO paho-mqtt
    

4.3.3 后端 (app.py) 关键技术实现

1 身份验证与安全

使用 Flask 的 session 机制实现登录保护。

  • login_required 装饰器: 保护 /, /api/history, /api/status, /api/config 等所有敏感路由,未登录强制跳转到 /login
  • 登录逻辑: 验证请求中提交的密码是否等于代码中设定的 ADMIN_PASSWORD ("Free")。
  • Session: 登录成功后设置 session['logged_in'] = True,并设置 24 小时过期 (PERMANENT_SESSION_LIFETIME)。

2 数据持久化:SQLite 替代 JSON

将原有的 history.json 升级为 tracker.db SQLite 数据库,解决了数据文件大后读写慢和跨天重置不准确的问题。

  • 初始化: init_db() 函数创建 locations 表,存储 (lat, lng, time)
  • 数据写入: save_point_db(lat, lng) 负责将实时坐标写入数据库。
  • 数据读取: load_history_db() 通过 SQL 语句 WHERE time LIKE 'YYYY-MM-DD%' 仅查询并返回当日的轨迹数据,实现了高效的“每日刷新”目标。

3 DTU 通信协议解析(on_message 函数)

on_message 是后端最复杂的模块,它需要识别和解析 DTU 设备可能发送的各种格式数据。

数据类型 示例格式 解析目标
实时位置 (透传) 119.5095_32.18769 经度和纬度
JSON 心跳/状态 {"imei":"86...", "csq":27} IMEI, CSQ 等状态参数
GPS 查询回执 config,gps,ok,1,E,113.xxx,N,32.xxx,0,20 经度, 纬度, 速度 (V), 海拔 (Altitude)
LBS 查询回执 config,lbsloc,ok,119.50,32.18 经度和纬度
系统状态回执 config,ssta,ok,4 SSTA 硬件状态码
CSQ/IMEI回执 config,csq,ok,25 CSQ 值

通过增加对 config,imei,ok, config,csq,ok 等纯文本回执的解析,确保了刷新状态按钮能正确更新页面数值。

4.3.4 前端 (index.html) 关键特性

1 地图核心功能

  • 坐标转换: 使用 wgs84ToGcj02 算法,将 DTU 传来的 WGS84 坐标转换为高德地图使用的 GCJ02 (火星坐标),解决了位置偏移问题。
  • 图层控制:
    • 移除 Leaflet 默认控件。
    • 新增 map-layer-control 开关,通过 toggleMapLayer() 函数在 vectorLayer (标准地图) 和 satelliteLayer (卫星地形) 之间切换显示。
  • 轨迹显示: 新增 toggleTrajectory 开关,通过 polyline.addTo(map)polyline.remove() 切换轨迹线的可见性。

2 顶部状态栏与交互

顶部状态栏集成了所有关键信息和交互点:

  • DTU 连接状态: 根据后端返回的 data.status (4=已连接) 动态显示 “已连接”/“未连接” 标签。
  • 实时参数: 明确显示 SSTA (系统状态, 4=正常), V (速度, km/h) 和 CSQ (信号值, >15良) 及其参考值。
  • 状态刷新按钮 (🔄): 点击后调用 /api/config 接口,批量发送 DTU 状态查询指令,确保信息最新。

3 持久化配置回显

页面加载后,通过 syncUI(data) 函数:

  • 读取 sys_config.json 中保存的 GPS/LBS 开关状态和周期。
  • 在左下角的 Badge 中正确显示 “开启 (30s)”“已关闭”,解决了页面刷新后状态显示为“未知”的问题。
  • 在“系统参数配置”弹窗中,自动勾选上次设置的开关状态(如“低功耗模式”)。

4.3.5 DTU 指令封装 (Config API)

所有用户操作最终都封装为 MQTT 指令发送给 DTU。

页面操作 cmd_type (Flask) DTU 指令示例
顶部刷新 refresh_status config,get,imei\r\n / config,get,csq\r\n / config,get,gps\r\n
LBS 刷新 refresh_lbs config,get,lbsloc\r\n
GPS 刷新 refresh_gps config,get,gps\r\n
GPS 设置 raw_cmd config,set,location,2,1,30,1,0,1,0\r\n
低功耗开关 raw_cmd config,set,lp,1\r\n
重启设备 raw_cmd config,set,reboot\r\n

4.4 源码存档

她的名字.7z

5.成果展示

5.1网页展示

5.2成品展示
后续做好密封防水即可