From e1f1ac902a4aac32b8182404c11237de25209ec0 Mon Sep 17 00:00:00 2001 From: kevin Date: Sat, 6 Jun 2026 15:56:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LICENSE | 21 +++ README.md | 514 ++++++++++++++++++++++-------------------------------- 2 files changed, 227 insertions(+), 308 deletions(-) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6b13aa6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 kevin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index ae32a60..f7b7fb8 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,142 @@ # Meshtastic MQTT Server -本程序启动一个本地 MQTT broker,并在转发客户端发布的消息前校验 Meshtastic MQTT payload。 +Meshtastic MQTT Server 是一个面向 Meshtastic MQTT 数据的本地服务:内置 MQTT broker,接收并校验 Meshtastic MQTT payload,同时提供 Web 管理与地图前端,用于查看节点、消息、位置、遥测、转发状态和管理配置。 -每条传入的 `PUBLISH` 都会先进入: +本文档重点说明部署与运行方式,不展开代码实现细节。 -```go -valid, _, record := mqtpp.MQTTPP(topic, payload, key, mqtpp.Options{}) -``` +## 后端功能 -- `valid == true`:保留原始 topic、payload、QoS、retain 等字段,正常转发给订阅匹配 topic 的客户端 -- `valid == false`:丢弃该消息,不转发给订阅客户端 +后端提供 MQTT broker、Meshtastic 数据校验、数据入库、Web API 和管理后台能力,主要功能包括: -当前不桥接到 `mqtt.meshtastic.org` 等上游 broker。 -## 运行 + +- 用户管理:支持创建管理员用户、修改管理员密码。 +- 屏蔽规则管理:支持设置节点屏蔽、IP 屏蔽和屏蔽词;屏蔽词可设置匹配方式、是否区分大小写、启用状态和原因。 +- 消息拦截:命中被屏蔽节点、被屏蔽 IP 或屏蔽词的消息会被拒绝,并写入丢弃记录。 +- MQTT 转发管理:支持配置多个 MQTT 转发器,设置源端、目标端、TLS、认证信息、转发 topic、方向、QoS、retain,并可查看转发运行状态或重启转发器。 +- 运行时设置:支持动态设置无法解密的加密 MQTT 包是否允许继续转发。 +- 地图源管理:支持配置地图瓦片源、默认地图源、启用状态、最大缩放级别、attribution 和是否通过后端代理地图瓦片。 +- 地图瓦片代理与缓存:可通过后端代理地图瓦片请求,并使用本地目录缓存。 +- 帮助内容管理:支持在管理后台编辑 Markdown 帮助内容,并提供预览与展示。 +- 数据库支持:支持 SQLite 和 MySQL。 +- Meshtastic payload 校验:在消息转发前校验 Meshtastic MQTT 数据包,无效数据会被拒绝并记录。 +- 数据解析与存储:解析并保存节点信息、地图上报、文本消息、位置、遥测、路由、traceroute 等数据。 + + + +## 运行环境 + +### 后端 + +- Go:`1.25.0` 或更高版本 +- 默认监听: + - MQTT:`0.0.0.0:1883` + - Web:`0.0.0.0:8080` + +### 前端 + +- Node.js:满足 Vite 8 要求 + - `^20.19.0`,或 + - `>=22.12.0` +- npm:随 Node.js 安装即可 + +建议生产环境使用当前 LTS 版本的 Node.js,并确保版本满足上述要求。 + +## 快速部署 + +### Linux 一键部署 + +在 Linux 下进入项目目录后,直接执行: ```bash -go run . +sudo bash install.sh ``` -默认监听: +安装脚本会自动拉取最新代码、安装前端依赖、构建前端、编译后端、安装到 `/opt/mesh_mqtt_go`,并创建和启动 `mesh_mqtt_go` systemd 服务。 -- host:`0.0.0.0` -- port:`1883` -- PSK:`AQ==` -- TLS:关闭 -- Web:`0.0.0.0:8080`,静态目录 `./dist` -- 数据库:SQLite -- SQLite 文件:Unix/Linux 为 `/srv/mesh_mqtt_go/mesh_mqtt_go.db`,Windows 测试为 `./win/etc/mesh_mqtt_go/mesh_mqtt_go.db` +### 手动构建前端 -首次启动会自动生成配置文件;之后每次启动都会检查配置项,缺失项会自动补全并写回。 +```bash +cd meshmap_frontend +npm install +npm run build +cd .. +``` -配置文件路径: +构建完成后,前端静态文件会生成到项目根目录的 `dist`,也就是从 `meshmap_frontend` 目录看是 `../dist`。 -- Unix/Linux:`/etc/mesh_mqtt_go/config.yaml` -- Windows 测试:`./win/etc/mesh_mqtt_go/config.yaml` +### 手动构建后端 -默认配置内容: +```bash +go build -o meshtastic_mqtt_server . +``` + +### 手动启动 + +```bash +./meshtastic_mqtt_server -web-static-dir ./dist +``` + +首次启动时,程序会自动生成默认配置文件。 + +默认配置路径: + +- Linux:`/etc/mesh_mqtt_go/config.yaml` +- Windows:`./win/etc/mesh_mqtt_go/config.yaml` + +默认数据路径: + +- Linux SQLite:`/srv/mesh_mqtt_go/mesh_mqtt_go.db` +- Windows SQLite:`./win/etc/mesh_mqtt_go/mesh_mqtt_go.db` + +默认地图瓦片缓存目录: + +- Linux:`/srv/mesh_mqtt_go` +- Windows:`./win/srv/mesh_mqtt_go` + +## 常用启动参数 + +```bash +./meshtastic_mqtt_server \ + -host 0.0.0.0 \ + -port 1883 \ + -web-host 0.0.0.0 \ + -web-port 8080 \ + -web-static-dir ./dist +``` + +常用参数说明: + +| 参数 | 说明 | 默认值 | +| --- | --- | --- | +| `-host` | MQTT broker 监听地址 | `0.0.0.0` | +| `-port` | MQTT broker 监听端口 | `1883` | +| `-psk` | Meshtastic channel PSK,Base64 格式 | `AQ==` | +| `-tls` | 启用 MQTT TLS | `false` | +| `-tls-cert` | MQTT TLS 证书文件 | 空 | +| `-tls-key` | MQTT TLS 私钥文件 | 空 | +| `-db-driver` | 数据库类型:`sqlite` 或 `mysql` | `sqlite` | +| `-sqlite-path` | SQLite 数据库文件路径 | 见默认数据路径 | +| `-mysql-dsn` | MySQL DSN | 空 | +| `-web` | 启用 Web 服务 | `true` | +| `-web-host` | Web 服务监听地址 | `0.0.0.0` | +| `-web-port` | Web 服务监听端口 | `8080` | +| `-web-socket-path` | Web Unix Socket 路径,Windows 不支持 | Linux 默认 `/opt/mesh_mqtt_go/web.sock` | +| `-web-static-dir` | 前端静态文件目录 | `./dist` | +| `-web-map-tile-cache-dir` | 地图瓦片缓存目录 | 见默认地图瓦片缓存目录 | +| `-admin-username` | Web 管理员用户名 | `admin` | + +管理员密码与会话密钥建议通过环境变量传入: + +```bash +export MESH_ADMIN_PASSWORD='change-me' +export MESH_ADMIN_SESSION_SECRET='replace-with-a-long-random-string' +./meshtastic_mqtt_server +``` + +## 配置文件示例 + +程序会自动生成并补全配置文件,也可以手动维护 `config.yaml`: ```yaml mqtt: @@ -46,19 +146,24 @@ mqtt: enabled: false cert_file: "" key_file: "" + meshtastic: psk: AQ== + database: driver: sqlite sqlite: path: /srv/mesh_mqtt_go/mesh_mqtt_go.db mysql: dsn: "" + web: enabled: true host: 0.0.0.0 port: 8080 + socket_path: "" static_dir: ./dist + map_tile_cache_dir: /srv/mesh_mqtt_go admin: username: admin password: admin @@ -66,319 +171,112 @@ web: session_secure: false ``` -配置优先级: +> 生产环境请修改默认管理员密码,并设置足够长、随机的 `session_secret`。如果通过 HTTPS 访问 Web 管理后台,建议将 `session_secure` 设置为 `true`。 -```text -内置默认值 < 配置文件 < 环境变量 < 命令行参数 -``` +## 使用 SQLite 部署 -也可以用命令行临时覆盖监听地址、PSK 和 TLS 设置: +SQLite 是默认数据库,适合单机部署: ```bash -go run . --host 127.0.0.1 --port 1883 --psk AQ== +mkdir -p /srv/mesh_mqtt_go +./meshtastic_mqtt_server \ + -db-driver sqlite \ + -sqlite-path /srv/mesh_mqtt_go/mesh_mqtt_go.db \ + -web-map-tile-cache-dir /srv/mesh_mqtt_go ``` -## 参数 +## 使用 MySQL 部署 -```text ---host MQTT broker listen host ---port MQTT broker listen port ---psk Base64 channel PSK used to try decrypting encrypted packets ---tls Enable MQTT TLS listener ---tls-cert MQTT TLS certificate file ---tls-key MQTT TLS private key file ---db-driver Database driver: sqlite or mysql ---sqlite-path SQLite database file path ---mysql-dsn MySQL database DSN ---web Enable Gin web server ---web-host Web server listen host ---web-port Web server listen port ---web-static-dir Web frontend static files directory -``` - -## Web 前端 - -开发模式: +如果需要使用 MySQL,启动时指定数据库驱动和 DSN: ```bash -go run . --web-host 127.0.0.1 --web-port 8080 -cd meshmap_frontend -npm run dev +./meshtastic_mqtt_server \ + -db-driver mysql \ + -mysql-dsn 'user:password@tcp(127.0.0.1:3306)/meshtastic?charset=utf8mb4&parseTime=True&loc=Local' ``` -生产构建: +## 启用 MQTT TLS + +准备证书和私钥后启动: ```bash -cd meshmap_frontend -npm run build -cd .. -go run . +./meshtastic_mqtt_server \ + -tls \ + -tls-cert /path/to/server.crt \ + -tls-key /path/to/server.key ``` -构建后的文件位于项目根目录 `dist/`,Gin 会提供静态文件服务;`/api` 路径保留给后端接口。 +## 访问服务 -管理页面位于 `/admin`,默认管理员账号为 `admin` / `admin`。生产环境请修改 `web.admin.password` 或设置 `MESH_ADMIN_PASSWORD`,并配置固定的 `web.admin.session_secret` 或 `MESH_ADMIN_SESSION_SECRET`;如果 `session_secret` 为空,程序会在启动时生成临时签名密钥,重启后需要重新登录。后台页面包括 `/admin` 服务状态、`/admin/users` 用户管理、`/admin/log/login` 登录日志、`/admin/discard_details` 丢弃数据。`/admin` 中的“丢弃消息”统计来自 `discard_details` 表记录数,点击可进入丢弃数据分页页。后台支持新增管理员用户和修改用户密码;密码使用 bcrypt hash 保存,API 不会返回密码 hash。修改密码不会立即使已签发 Session 失效,当前 Session 到期或退出登录后才需要使用新密码。登录成功和失败都会记录到登录日志,包含用户名、结果、原因、来源地址、User-Agent 和时间。管理员可在主页右键删除聊天消息、地图节点或节点列表记录;删除节点会删除 `nodeinfo` 和 `map_report` 当前状态,不会删除历史消息、位置、遥测等 append 记录,后续收到新的节点上报时可能重新出现。 +启动后可访问: -常用 API: +- Web 前端:`http://服务器地址:8080/` +- 健康检查:`http://服务器地址:8080/api/health` +- MQTT broker:`服务器地址:1883` -```text -GET /api/health -POST /api/admin/login -POST /api/admin/logout -GET /api/admin/me -GET /api/admin/mqtt/status -GET /api/admin/log/login -GET /api/admin/users -POST /api/admin/users -PUT /api/admin/users/:id/password -DELETE /api/admin/text-messages/:id -DELETE /api/admin/nodes/:id -GET /api/nodeinfo -GET /api/nodeinfo/:id -GET /api/map-reports -GET /api/map-reports/:id -GET /api/nodes # /api/nodeinfo 的兼容别名 -GET /api/nodes/:id # /api/nodeinfo/:id 的兼容别名 -GET /api/text-messages -GET /api/discard-details -GET /api/positions -GET /api/telemetry -GET /api/routing -GET /api/traceroute +Web 管理后台默认账号: + +- 用户名:`admin` +- 密码:`admin` + +生产环境请务必修改默认密码。 + +## systemd 部署示例 + +以下示例假设: + +- 后端可执行文件位于 `/opt/mesh_mqtt_go/meshtastic_mqtt_server` +- 前端静态文件位于 `/opt/mesh_mqtt_go/dist` +- 数据与缓存目录位于 `/srv/mesh_mqtt_go` +- 配置文件位于 `/etc/mesh_mqtt_go/config.yaml` + +创建服务文件 `/etc/systemd/system/mesh_mqtt_go.service`: + +```ini +[Unit] +Description=Meshtastic MQTT Server +After=network.target + +[Service] +Type=simple +WorkingDirectory=/opt/mesh_mqtt_go +ExecStart=/opt/mesh_mqtt_go/meshtastic_mqtt_server -web-static-dir /opt/mesh_mqtt_go/dist +Environment=MESH_ADMIN_PASSWORD=change-me +Environment=MESH_ADMIN_SESSION_SECRET=replace-with-a-long-random-string +Restart=on-failure +RestartSec=5s + +[Install] +WantedBy=multi-user.target ``` -## TLS 配置示例 - -```yaml -mqtt: - host: 0.0.0.0 - port: 8883 - tls: - enabled: true - cert_file: ./certs/server.crt - key_file: ./certs/server.key -meshtastic: - psk: AQ== -``` - -启用 TLS 后,`cert_file` 和 `key_file` 必须指向可读取的证书和私钥文件。 - -## 数据库持久化 - -程序默认启用 SQLite,数据库表迁移和操作由 GORM 执行,并持久化以下数据: - -- `login_log`:追加保存后台登录成功和失败日志 -- `discard_details`:追加保存 `MQTTPP` 判定无效而被 broker 丢弃的数据,raw payload 使用 base64 保存 -- `nodeinfo`:保存 `type == "nodeinfo"` 的节点身份和设备信息 -- `map_report`:保存 `type == "map_report"` 的地图报告信息,前端地图从该表读取 -- `text_message`:追加保存 `type == "text_message"` 的聊天消息 -- `position`:追加保存 `type == "position"` 的位置包 -- `telemetry`:追加保存 `type == "telemetry"` 的遥测包 -- `routing`:追加保存 `type == "routing"` 的路由控制包 -- `traceroute`:追加保存 `type == "traceroute"` 的路径追踪包 - -`nodeinfo` / `map_report` 规则: - -- 两张表都以 `node_id`(即解析结果中的 `from`,例如 `!a8dfd867`)作为主键 -- `nodeinfo` 只保存节点身份和设备字段,例如 `user_id`、名称、硬件型号、角色、授权状态和公钥 -- `map_report` 只保存地图报告字段,例如名称、硬件型号、角色、固件版本、区域、调制预设、经纬度、海拔、位置精度和在线节点数 -- 重复收到同一节点时不会插入重复行,只更新 `updated_at`、`content_json` 和本次记录中有值的字段 -- `first_seen_at` 保留第一次写入时间 -- `content_json` 分别保存最新一次 `nodeinfo` 或 `map_report` 的完整解析结果 JSON -- 旧版本创建的 `nodeinfo_map` 融合表不会被自动删除,新版本不再写入该表;新表会从新收到的数据开始填充 - -`text_message` 规则: - -- 使用自增 `id` 作为主键 -- 每条聊天消息都会新增一行,不做去重 -- 保存 `from_id`、`from_num`、`text`、`payload_hex`、topic、packet 元数据和完整 `content_json` -- 保存 MQTT 客户端信息:`mqtt_client_id`、`mqtt_username`、`mqtt_listener`、`mqtt_remote_addr`、`mqtt_remote_host`、`mqtt_remote_port` - -`position` / `telemetry` / `routing` / `traceroute` 规则: - -- 都使用自增 `id` 作为主键 -- 每条有效记录都会新增一行,不做去重 -- 保存通用 packet 元数据、MQTT 客户端信息和完整 `content_json` -- `position` 额外保存经纬度、海拔、时间、定位来源、精度、速度、卫星数等字段 -- `telemetry` 额外保存 `telemetry_type`,并把动态 `metrics` 对象保存为 `metrics_json` -- `routing` 和 `traceroute` 当前保存通用元数据和完整 JSON;后续如果解析更多 payload 字段,可继续扩展列 - -查询最近聊天消息示例: - -```sql -SELECT id, created_at, from_id, text, mqtt_remote_host -FROM text_message -ORDER BY id DESC -LIMIT 20; -``` - -查询位置包示例: - -```sql -SELECT id, created_at, from_id, latitude, longitude, altitude -FROM position -ORDER BY id DESC -LIMIT 20; -``` - -查询遥测包示例: - -```sql -SELECT id, created_at, from_id, telemetry_type, metrics_json -FROM telemetry -ORDER BY id DESC -LIMIT 20; -``` - -SQLite 默认路径: - -- Unix/Linux:`/srv/mesh_mqtt_go/mesh_mqtt_go.db` -- Windows 测试:`./win/etc/mesh_mqtt_go/mesh_mqtt_go.db` - -MySQL 配置示例: - -```yaml -database: - driver: mysql - sqlite: - path: /srv/mesh_mqtt_go/mesh_mqtt_go.db - mysql: - dsn: mesh_user:mesh_pass@tcp(127.0.0.1:3306)/mesh_mqtt_go?parseTime=true&charset=utf8mb4,utf8 -``` - -使用 MySQL 时,需要提前创建好 database/schema。 - -## 转发规则 - -程序监听所有传入 publish。payload 能被 `mqtpp.MQTTPP` 解析时,认为 `valid == true`,broker 会继续把原始 MQTT 消息转发给订阅者;解析失败时,认为 `valid == false`,broker 会拒绝并丢弃该 publish。 - -`empty_packet` 仍然属于 `valid == true`,会被转发;只是控制台默认不显示它。 - -无法解密的加密包会输出为 `encrypted_packet`,属于 `valid == false`,因此会被拒绝并丢弃。 - -丢弃的 publish 会写入 `discard_details`,记录 topic、错误原因、payload 长度、base64 raw payload、MQTT 客户端信息和完整 `content_json`。 - -## 本地验证 - -一个终端启动 broker: +启用并启动服务: ```bash -go run . --host 127.0.0.1 --port 1883 --psk AQ== +sudo systemctl daemon-reload +sudo systemctl enable --now mesh_mqtt_go +sudo systemctl status mesh_mqtt_go ``` -另一个终端订阅: +查看日志: ```bash -mosquitto_sub -h 127.0.0.1 -p 1883 -t '#' +sudo journalctl -u mesh_mqtt_go -f ``` -发布非法 payload: +## 生产环境建议 -```bash -mosquitto_pub -h 127.0.0.1 -p 1883 -t 'msh/US/test' -m 'not protobuf' -``` +- 修改默认管理员密码。 +- 设置随机且足够长的 `MESH_ADMIN_SESSION_SECRET`。 +- 使用反向代理提供 HTTPS。 +- 如果 Web 管理后台通过 HTTPS 访问,启用安全 Cookie。 +- 根据实际情况开放防火墙端口: + - MQTT:`1883` + - MQTT TLS:自定义端口或仍使用 `1883` + - Web:`8080` 或反向代理端口 +- 定期备份数据库文件或 MySQL 数据库。 +- 为地图瓦片缓存目录预留足够磁盘空间。 -订阅端应该收不到该消息。 +## 开源协议 -要验证 valid 消息转发,请使用真实 Meshtastic MQTT payload 发布到本 broker;订阅匹配 topic 的客户端应收到原始消息,broker 控制台会打印解析后的 `record`。 - -## 控制台颜色说明 - -程序会按数据包类型使用不同背景色,方便快速区分消息类型。 - -| 背景色 | type | portnum | 含义 | -|---|---|---|---| -| 绿色 | `nodeinfo` | `NODEINFO_APP` | 节点信息包,包含节点 ID、长名称、短名称、硬件型号、角色、公钥等 | -| 蓝色 | `map_report` | `MAP_REPORT_APP` | 地图报告包,包含节点名称、硬件、固件版本、区域、调制预设、位置等地图信息 | -| 紫色 | `text_message` | `TEXT_MESSAGE_APP` | 聊天文本消息 | -| 青色 | `position` | `POSITION_APP` | 位置包,会展开解析经纬度、海拔、时间、定位来源、精度、速度、卫星数等字段 | -| 黄色 | `telemetry` | `TELEMETRY_APP` | 遥测包,会展开解析设备、电源、环境、空气质量、本地统计、健康、主机和流量管理指标 | -| 灰色 | `routing` | `ROUTING_APP` | 路由控制包,常见于 ACK、NAK、路由错误等控制信息 | -| 灰色 | `traceroute` | `TRACEROUTE_APP` | 路径追踪包,用于 mesh 网络路径探测 | -| 红色 | error record | - | protobuf 解析失败、payload 解码失败或其他处理错误 | -| 无颜色 | `encrypted_packet` | - | 加密包但当前 PSK/频道 hash 无法解密;这不一定是错误 | -| 无颜色 | `decoded_packet` | 其他 portnum | 已解码/已解密,但程序尚未细分的其他应用包 | - -## 已展开解析的数据包 - -### `position` / `POSITION_APP` - -位置包会从 Meshtastic `Position` payload 中展开常用字段,包括: - -- `latitude` / `longitude`:经纬度,已从 `latitude_i` / `longitude_i` 转换为浮点角度 -- `altitude`:海拔,单位米 -- `time` / `timestamp`:位置相关时间戳 -- `location_source`:定位来源,例如 `LOC_MANUAL`、`LOC_INTERNAL`、`LOC_EXTERNAL` -- `altitude_source`:海拔来源,例如 `ALT_MANUAL`、`ALT_INTERNAL`、`ALT_BAROMETRIC` -- `altitude_hae` / `altitude_geoidal_separation`:HAE 海拔和大地水准面分离值 -- `pdop` / `hdop` / `vdop`:定位精度因子,已从 1/100 单位转换为浮点值 -- `gps_accuracy`:GPS 精度,单位 mm -- `ground_speed`:地面速度,单位 m/s -- `ground_track`:地面航迹角,已从 1/100 度转换为度 -- `fix_quality` / `fix_type` / `sats_in_view`:GPS fix 质量、类型和可见卫星数 -- `sensor_id` / `next_update` / `seq_number` / `precision_bits`:传感器、更新间隔、序列号和位置精度位数 - -### `telemetry` / `TELEMETRY_APP` - -遥测包会输出: - -- `time`:遥测时间戳 -- `telemetry_type`:具体 telemetry variant -- `metrics`:展开后的指标对象 - -当前支持的 `telemetry_type`: - -| telemetry_type | 含义 | 常见 metrics | -|---|---|---| -| `device_metrics` | 设备状态 | `battery_level`、`voltage`、`channel_utilization`、`air_util_tx`、`uptime_seconds` | -| `environment_metrics` | 环境传感器 | `temperature`、`relative_humidity`、`barometric_pressure`、`gas_resistance`、`lux`、`wind_speed`、`rainfall_1h` 等 | -| `air_quality_metrics` | 空气质量 | `pm25_standard`、`pm100_standard`、`co2`、`pm_temperature`、`pm_humidity`、`pm_voc_idx` 等 | -| `power_metrics` | 多通道电源数据 | `ch1_voltage`、`ch1_current` 到 `ch8_voltage`、`ch8_current` | -| `local_stats` | 本地 mesh 统计 | `num_packets_tx`、`num_packets_rx`、`num_online_nodes`、`heap_free_bytes`、`noise_floor` 等 | -| `health_metrics` | 健康数据 | `heart_bpm`、`spO2`、`temperature` | -| `host_metrics` | Linux/Portduino 主机指标 | `uptime_seconds`、`freemem_bytes`、`diskfree1_bytes`、`load1`、`load5`、`load15`、`user_string` | -| `traffic_management_stats` | 流量管理统计 | `packets_inspected`、`position_dedup_drops`、`rate_limit_drops`、`unknown_packet_drops` 等 | - -## 过滤规则 - -程序默认不显示 `empty_packet`。 - -`empty_packet` 指 `MeshPacket` 中没有 `decoded` 或 `encrypted` payload 的包,只包含类似 `from`、`to`、`id`、`via_mqtt` 等包头信息。根据固件源码分析,这类包通常不是普通业务数据,更多是 MQTT 回显/隐式 ACK 相关的元信息,对查看节点信息、地图报告和聊天内容价值较低。 - -## 输出示例 - -节点信息包: - -```json -{"type":"nodeinfo","portnum":"NODEINFO_APP","from":"!a8dfd867","long_name":"Kabi Matrix 🖥️","short_name":"KaMX","hw_model":"PRIVATE_HW","role":"CLIENT_MUTE"} -``` - -地图报告包: - -```json -{"type":"map_report","portnum":"MAP_REPORT_APP","from":"!675c9803","long_name":"PaulHome","latitude":42.51043,"longitude":-83.08624999999999,"hw_model":"PORTDUINO"} -``` - -聊天消息包: - -```json -{"type":"text_message","portnum":"TEXT_MESSAGE_APP","from":"!12345678","text":"hello mesh"} -``` - -位置包: - -```json -{"type":"position","portnum":"POSITION_APP","from":"!12345678","latitude":42.51043,"longitude":-83.08625,"altitude":192,"location_source":"LOC_INTERNAL","sats_in_view":8} -``` - -遥测包: - -```json -{"type":"telemetry","portnum":"TELEMETRY_APP","from":"!12345678","telemetry_type":"device_metrics","metrics":{"battery_level":85,"voltage":4.1,"channel_utilization":2.3,"air_util_tx":0.5,"uptime_seconds":12345}} -``` - -解密失败的加密包: - -```json -{"type":"encrypted_packet","decrypt_success":false,"decrypt_status":"channel hash mismatch","encrypted_len":43} -``` +本项目采用 MIT License 开源。详见项目许可证文件。 \ No newline at end of file