kevin
99fb474bcf
ai服务状态更新
2026-07-01 11:55:37 +08:00
kevin
f6fa167d76
更新ai服务提醒
2026-07-01 11:26:08 +08:00
kevin
01c7275763
admin 页面 MQTT 服务状态增加去重队列长度显示
2026-06-30 12:18:40 +08:00
kevin
4782e84c15
添加 MQTT 消息去重队列:Hook 层基于 payload+topic hash 去重,TTL 15 秒,定时清理
2026-06-30 12:10:29 +08:00
kevin and Claude Fable 5
bce6b70e8f
增强 MQTT 消息拒绝诊断功能
...
问题:
- TCP_NODELAY 修复了 TCP ACK 延迟,但设备仍然重发
- 需要确定是消息被服务器拒绝,还是设备端 bug
改进内容:
- OnPublish 中添加详细的拒绝日志输出
- 当消息验证失败时,输出 client_id、topic、qos、错误原因
- 当消息被屏蔽时,输出屏蔽类型和原因
- 帮助快速诊断 QoS0 重发的根本原因
新增文档:
- doc/QOS0_RETRANSMIT_ANALYSIS.md - 深度分析重发问题的各种原因
- doc/DIAGNOSTIC_GUIDE.md - 完整的诊断指南和解决方案
使用方法:
./meshtastic_mqtt_server --console-log-mqtt=true
观察日志中是否有:
[mqtt] PUBLISH rejected: ... - 消息被拒绝(服务器问题)
[mqtt] PUBLISH blocked: ... - 消息被屏蔽(配置问题)
如果没有 rejected/blocked 日志但仍重发,则是设备端 bug。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-06-23 21:42:50 +08:00
kevin and Claude Fable 5
2f83308dce
修复 LLM Provider 配置热更新问题
...
问题:在 /admin/llm/api 页面修改 AI 提供商配置后,配置没有立即生效,AI 依然使用旧的提供商工作
根本原因:
- LLM Provider 配置在程序启动时加载到内存 (llm.State)
- 管理后台修改配置时,只更新了数据库,内存配置未更新
- AI 继续使用内存中的旧配置
解决方案:
1. 为 llm.State 添加动态更新方法 (UpdateProvider/AddProvider/RemoveProvider)
2. 在 AI Service 中暴露配置更新接口,支持运行时重新加载
3. 在配置保存后自动触发内存配置重新加载
4. 创建新的 LLM Client 使新配置立即生效
关键特性:
- 线程安全:使用 sync.RWMutex 保护并发访问
- 容错处理:重新加载失败不影响数据库更新
- 无需重启:配置修改后立即生效
- 完整测试:添加单元测试验证功能
修改文件:
- internal/llm/state.go: 添加配置更新方法
- internal/ai/service.go: 添加配置重新加载接口
- internal/llmadmin/admin_llm_routes.go: 配置更新时触发重新加载
- internal/web/web.go: 传递 AI Service 到路由
- main.go: 连接组件
- internal/llm/state_test.go: 新增单元测试
- internal/web/map_tile_proxy_routes_test.go: 修复测试
测试:
- ✅ 所有现有测试通过
- ✅ 新增测试覆盖核心功能
- ✅ 项目成功编译
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-06-23 21:13:31 +08:00
kevin and Claude Fable 5
ec24e70275
修复 MQTT QoS0 消息重发问题
...
问题:
- 设备发送 QoS0 消息后服务器未及时响应 TCP ACK
- 导致设备重发 3 次
- 有时能一次成功,有时需要多次重发
根本原因:
- TCP Nagle 算法延迟小数据包(包括 TCP ACK)40-200ms
- QoS0 不需要 MQTT 应用层 PUBACK,但依赖 TCP 层 ACK
- TCP ACK 延迟触发客户端 TCP 重传机制
解决方案:
- 在 OnConnect hook 中设置 TCP_NODELAY
- 禁用 Nagle 算法,确保 TCP ACK 立即发送
- TCP ACK 延迟从 40-200ms 降低到 ~0.05ms
测试:
- 添加 tcp_nodelay_test.go 验证修复
- 平均往返延迟:54µs
- 符合 MQTT broker 行业最佳实践(Mosquitto、EMQX、HiveMQ 均默认启用)
文档:
- doc/TCP_ACK_FIX_CN.md - 中文详细说明
- doc/TCP_ACK_FIX.md - 英文详细说明
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-06-23 21:04:00 +08:00
kevin
54df706ca7
基本完成
2026-06-20 02:15:15 +08:00
kevin
fd766be731
up
2026-06-20 01:45:24 +08:00
kevin and Claude
b9c2b8f0bd
fix(llm): 工具路由配置修改后立即生效,不再硬编码 system prompt
...
toolrouter 每轮调用都从 DB 读取最新配置,/admin/llm/api 保存后下一条消息即生效,
无需重启。ai.NewService 启动时从 DB 加载初始配置,移除硬编码 prompt 覆盖用户配置的问题。
Co-Authored-By: Claude <noreply@anthropic.com >
2026-06-20 00:41:28 +08:00
kevin
fd66162d57
feat(mqtt): client_id 冲突时自动加 4 位随机后缀
...
同一 Meshtastic 节点被多台 Android 同时连时,broker 按 [MQTT-3.1.4-3]
强制顶号会让两边互相踢,日志被刷屏且无法稳定收发。
OnConnect 里检测 server.Clients 中是否已有未关闭的同 ID 客户端,命中
就把当前连接的 cl.ID 改成 "原ID-xxxx"(4 位 hex),避开顶号路径。
打 mqtt_client_id_renamed 日志记录原/新 ID 与双方 remote。
2026-06-19 22:51:34 +08:00
kevin and Claude
8bbe40c230
feat(llm): console_log.llm 控制可读单行流程日志,并追踪路由 AI 决策
...
autoreply.Service 增加 consoleLog 字段和 logf 辅助;processMessage 中
原本的 printJSON map dump 全部替换为 [llm] 前缀的单行 key=value 输出。
关闭开关时整条链路静默。
把原本传 nil 给 toolrouter.RunAgentToolLoop 的 emit 接进来,将
stream.Frame trace 帧渲染为可读行,区分三类来源:
- 主 AI:main_model / completion / 最终 reply
- 路由 AI:router=<model> prepare/decide iter=N → call_tools=[...] / no_tool
- 工具调用:tool=<name> args=... / result(Nms)=... / ERROR ...
ai.Config 增加 ConsoleLog 字段,由 main.go 传入 cfg.ConsoleLog.LLM,
再透传给 autoreply.NewService。
Co-Authored-By: Claude <noreply@anthropic.com >
2026-06-19 17:45:21 +08:00
kevin and Claude
49a287e6e7
feat: console_log.meshtastic 控制 packet 控制台输出;新增每客户端报文统计
...
- ConsoleLogConfig 增加 Meshtastic 字段(默认 true);旧配置自动补齐
- meshtasticFilterHook 增加 packetConsoleLog;OnPublish 中根据开关调用
新的 printMeshtasticRecord 输出可读单行(key=value、按 type 着色),
替代原来的 JSON dump;事件型 printJSON 调用保持不变
- 新增 internal/mqttforward/ClientStats,按 client_id 累计 in/out 报文计数
- meshtasticFilterHook 多挂 OnPacketRead / OnPacketSent / OnDisconnect
事件,用于增减计数;Provides() 同步声明
- AdminMQTTClient JSON 视图删除 RemoteHost/RemotePort,新增
packets_in / packets_out;前端 types.ts、AdminDashboard.vue 同步更新
Co-Authored-By: Claude <noreply@anthropic.com >
2026-06-19 17:09:00 +08:00
kevin and Claude
937580e24f
feat(mqtt): console_log.mqtt 控制连接/断开/订阅/取消订阅日志
...
为 meshtasticFilterHook 增加 consoleLog 字段;当 console_log.mqtt=true 时
向 stderr 输出 4 类事件(带 client_id、username、remote IP:port):
- OnSessionEstablished → [mqtt] connect ... (认证后才打,避开被 IP 屏蔽拒掉的客户端)
- OnDisconnect → [mqtt] disconnect ... (含 expire 和 mochi 上报的断开原因)
- OnSubscribed → [mqtt] subscribe ... (每个 filter 一行)
- OnUnsubscribed → [mqtt] unsubscribe ... (每个 filter 一行)
Provides() 同步多声明这 4 个事件类型;关闭开关时各 handler 立即返回。
Co-Authored-By: Claude <noreply@anthropic.com >
2026-06-19 16:21:55 +08:00
kevin and Claude
52da224a19
refactor(config): console_log 提到顶层并细分 web/mqtt/llm/sql;data_dir 归入 ai
...
- 新增顶层 ConsoleLogConfig{Web, MQTT, LLM, SQL},默认全 true,方便后续按模块扩展
- WebConfig.ConsoleLog 移除;NewRouter/NewHTTPServer 改为显式接 consoleLog 参数
- AIConfig 增加 DataDir,原 Config.DataDir(仅 ai 模块使用)下沉到 ai.data_dir
- OpenStore(cfg, consoleLog) 通过 console_log.sql 控制 gorm logger 级别(Warn/Silent)
- gorm logger 始终设 IgnoreRecordNotFoundError=true,修掉 GetBoolRuntimeSetting
正常缺省路径仍刷屏 'record not found' 的噪声
- 同步更新 install.sh 模板、win/etc 默认 yaml 与所有测试调用点
Co-Authored-By: Claude <noreply@anthropic.com >
2026-06-19 16:13:18 +08:00
kevin and Claude
d57dff58f3
重构:把剩余 12 个顶层包全部迁到 internal/
...
继续之前的重构:把根目录残留的非数据/资源类子目录(agents、agenttool、ai、
autoreply、completion、conversation、llm、message、mqtpp、stream、
toolmanager、toolrouter)一并搬到 internal/ 下,并把全工程引用它们的
import 路径从 "meshtastic_mqtt_server/<x>" 重写为
"meshtastic_mqtt_server/internal/<x>"。
变更
- git mv 12 个顶层目录进 internal/,无函数体改动。
- 全工程 sed 把 import path 加上 internal/ 前缀,包括 main.go、
internal/bot/bot_service.go、internal/store/bot_store.go 中对 mqtpp
的引用,以及 ai 子系统内部 agents/agenttool/autoreply/conversation/
llm/toolmanager/toolrouter 之间的相互引用。
验证
- go build ./... 通过;go test ./... 全部包通过。
- AI 自动回复链路(main → ai.NewService → autoreply.Service → botSender)
保持不变,仅 import 路径调整。
- 根目录最终只剩 main.go / main_test.go / internal/ 加 go.mod / go.sum
与数据资源目录(dist、doc、firmware、py、win、meshmap_frontend)。
Co-Authored-By: Claude <noreply@anthropic.com >
2026-06-18 18:43:42 +08:00
kevin and Claude
46916d9a93
重构:main.go 直接 import 各 internal/ 子包,删除全部 bridge
...
最后一步:把 main.go 里所有指向桥接小写名的引用(store / config /
blocking / bot / runtimesettings / mqttforward / web 等)改写成直接调用
internal/* 子包的导出 API,从而拆掉所有 *_bridge.go。
变更点
- main.go 顶部 import 区改为引用 11 个 internal/ 子包:auth、blocking、
bot、config、mqttforward、runtimesettings、store、web 等。
- meshtasticFilterHook 字段类型改为 *storepkg.WriteQueue / *blockingpkg.Cache
/ *rspkg.Cache / *mqttforwardpkg.Stats;不再依赖 main 包内别名。
- mqttClientInfoFromClient 返回 storepkg.MQTTClientInfo(之前为 main 包别名)。
- run() 里 newSessionManager → auth.NewManager;newRouter → webpkg.NewRouter;
serveHTTPUnixSocket → webpkg.ServeUnixSocket;mqttRuntimeStatus →
webpkg.MQTTRuntimeStatus;botSendTextRequest → botpkg.SendTextRequest;
newBlockingCache / newRuntimeSettingsCache / newMQTTForwardManager 都改为
对应包的 New / NewManager。
- main_test.go 里的 BlockingViolationForRecord 测试改用 testutil.OpenStore
+ blockingpkg.New,全部通过 store.Store 的公开 API 构造数据,不再需要
根目录 test_helpers_test.go。
删除根目录文件
- config.go、auth.go(已删)、blocking_bridge.go、bot_bridge.go、
help_bridge.go、llmadmin_bridge.go、mapsource_bridge.go、
mqttforward_bridge.go、runtime_settings_bridge.go、sign_bridge.go、
store_bridge.go、web_bridge.go、test_helpers_test.go。
最终结果
- 根目录只剩 main.go (~370 行) 和 main_test.go (~110 行)。
- internal/ 下 13 个独立子包:auth / blocking / bot / config / help /
llmadmin / mapsource / mqttforward / runtimesettings / sign / store /
store/testutil / web / webutil。
- go build ./... / go test ./... 全部通过;测试数量与重构前一致;
go build . 可以产出可执行二进制(约 50 MB)。
Co-Authored-By: Claude <noreply@anthropic.com >
2026-06-18 18:30:00 +08:00
kevin and Claude
eff4972668
重构:拆出 internal/config 与 internal/store 子包
...
把工程根目录中和"配置加载"、"数据存储"两个领域相关的全部 Go 文件迁到
internal/ 下的子包,按功能分组的第一阶段成果。
internal/config/
- 从 config.go 抽出 Config / MQTTConfig / WebConfig / DatabaseConfig 等
类型并大写导出,函数改名 Default/Load/Write/Validate/BuildTLS 等。
- 测试随被测代码迁移成 package config 的内部测试。
- 根目录留 config.go 作桥接:用 type alias 让旧的小写名(config /
mqttConfig / databaseConfig 等)继续可用,避免修改 30+ 处调用方。
internal/store/
- 把 db.go、store_query.go、db_write_queue.go 与 13 个 *_store.go 一并
迁入;26 个 *Record 类型与 store 同包以避免循环依赖。
- store -> Store;50+ 标识符从小写未导出改为大写导出(包括 record、
ListOptions、错误变量、bot/llm/runtime 常量、helpers 等)。
- 新增 DB() / Driver() 访问器供 ai 子系统使用,避免直接访问私有字段。
- bot_pki_store.go 独立出来,把 PKI 解密所需的 store 方法集中归类。
- helpers.go 提供 hashPassword / uint32FromRecord / printJSON 等以前在
其他根目录文件中的辅助;test_helpers_test.go 提供 verifyPassword
与 publicMapTileSourceDTO 让测试可以本地运行而不依赖 main 包。
根目录新增:
- store_bridge.go:完整 type-alias / 函数包装层,把 internal/store 的
导出名映射回旧的小写名,让 admin_*_routes.go、web.go、bot_service.go
等仍未迁出的文件继续编译。后续步骤把它们迁到各自领域包后可逐步删除。
- test_helpers_test.go:根目录测试沿用 openTestStore 的入口。
go build ./... 与 go test ./... 全部通过;测试数量与重构前一致。
Co-Authored-By: Claude <noreply@anthropic.com >
2026-06-18 13:56:36 +08:00
kevin
fcd230cb5b
写成屎山了
2026-06-18 08:35:09 +08:00
kevin
45822fd333
工具路由还没实现
2026-06-18 08:14:09 +08:00
kevin
ce07792c4b
up
2026-06-17 23:54:38 +08:00
kevin and Claude
0f04047517
支持 Web 端口和 Sock 同时启用
...
Co-Authored-By: Claude <noreply@anthropic.com >
2026-06-16 19:36:47 +08:00
kevin
67330d4656
优化机器人ack
2026-06-14 19:56:20 +08:00
kevin
757eb852fd
更新机器人接收功能
2026-06-14 19:41:52 +08:00
kevin
609462252c
机器人功能还差发送nodeinfo
2026-06-12 19:24:40 +08:00
kevin
2e96faf5a2
Merge branch 'main' of https://git.lmve.net/kevin/meshtastic_mqtt_server
...
# Conflicts:
# meshmap_frontend/src/App.vue
# web.go
2026-06-12 18:15:30 +08:00
kevin
b645907c52
新增机器人功能
2026-06-12 18:07:53 +08:00
kevin
563d609121
服务器代理地图数据
2026-06-06 12:01:46 +08:00
kevin
fb1971da72
增加转发开关
2026-06-05 20:03:52 +08:00
kevin
d962ccf9af
新增mqtt转发功能
2026-06-05 18:49:30 +08:00
kevin
081600eff0
异步保存sql消息
2026-06-05 13:34:54 +08:00
kevin
6fb6fc4f10
修复跨端问题
2026-06-04 17:49:31 +08:00
kevin
25decaba71
部署脚本
2026-06-04 16:29:52 +08:00
kevin
2e6eab3e01
屏蔽词功能ok
2026-06-04 15:20:40 +08:00
kevin
f73d79b7d4
基本功能差不多完成
2026-06-04 09:52:57 +08:00
kevin
7c1b30b3a0
统计相关更新
2026-06-04 00:09:16 +08:00
kevin
9221a53617
新增后台管理
2026-06-03 23:29:21 +08:00
kevin
3ae2ffa098
分表
2026-06-03 22:34:25 +08:00
kevin
26126771f4
up
2026-06-03 20:26:15 +08:00
kevin
9748a1e681
添加前端
2026-06-03 18:31:15 +08:00
kevin
6ccced6cd3
新增几个数据表
2026-06-03 17:14:49 +08:00
kevin
8c1e1ef414
text_message 表设计与实现
2026-06-03 15:08:32 +08:00
kevin
d887845909
增加数据库支持
2026-06-03 14:09:48 +08:00
kevin
44dfb14cf4
增加配置文件
2026-06-03 13:41:54 +08:00
kevin
618bde456a
将mqtt客户端改成mqtt服务端
2026-06-03 11:52:55 +08:00
kevin
2df622f8e1
up
2026-06-03 01:55:11 +08:00
kevin
c279181123
分离功能
2026-06-03 01:41:10 +08:00
kevin
5ab183af90
解码功能完成
2026-06-03 00:26:25 +08:00
kevin
0a9f54f2c3
go重构
2026-06-03 00:04:05 +08:00