本文件记录本项目开发/维护时需要注意的关键信息,方便下次快速上手。
注意每次改动需要更新本文件,这非常重要!!!!!!!!
hostname=ido,aarch64),作为 DTU(数据传输单元)运行。dzxj_dtu —— 串口(MODBUS-RTU/RS485) ↔ MQTT 网关,带 Web 管理界面(Flask + Socket.IO + Vue 前端)。/root/dzxj_dtu/,代码库在本仓库。192.168.199.149(远程管理用),wlan0 = 192.168.10.3,实际 IP 见串口屏显示。dzxj_dtu.service → /root/dzxj_dtu/backend/app.py(venv Python)frpc.service → FRP 客户端(stcp 映射 SSH + http 域名映射 80 端口)easytier.service → EasyTier VPN(组网)mosquitto.service → 本地 MQTT Broker(:1883)nginx.service、mysql.service 等149 上跑 frpc(仅客户端,不跑 frps),通过 stcp 模式把本地 22 端口映射到公网 frps 服务器。
device.wenhq.top:8580,token = gx@12345678(frps 部署在外部,不在本设备)。/opt/frp/frpc.tomlsystemctl status frpc / systemctl restart frpcfrpc 配置摘要:
serverAddr = "device.wenhq.top"
serverPort = 8580
auth.method = "token"
auth.token = "gx@12345678"
[[proxies]]
name = "149-ssh"
type = "stcp"
localIP = "127.0.0.1"
localPort = 22
secretKey = "149-ssh-sk"
访问端(你的电脑)需要配置 visitor 才能连:
serverAddr = "device.wenhq.top"
serverPort = 8580
auth.method = "token"
auth.token = "gx@12345678"
[[visitors]]
name = "149-ssh"
type = "stcp"
serverName = "149-ssh"
sk = "149-ssh-sk"
bindPort = 6000
然后 ssh root@127.0.0.1 -p 6000(密码 123456)即可连到 149 的 22 端口。
frpc 里已有 http 代理,把本地 80 端口映射成 pxj 子域名:
[[proxies]]
name = "149-http"
type = "http"
localIP = "127.0.0.1"
localPort = 80
subDomain = "pxj"
通过 http://pxj.<frps主域名> 访问(具体子域解析规则由 frps 端配置决定)。
/etc/systemd/system/easytier.servicepxjdtu / secret 123456,peer 服务器 remote-mange.dnnbuild.com:25700--no-tun 模式(本设备内核无 tun 模块,/dev/net/tun 不可用,modprobe tun 失败)。--port-forward tcp://0.0.0.0:2222/10.11.21.0:22 做端口转发,访问 127.0.0.1:2222 可到 MacBook 的 SSH(仅演示,10.11.21.0 是当时 peer 的虚拟 IP,会变)。/home/admin/easytier-cli node / peer / peer-center。--no-tun 模式下虚拟 IP(10.11.21.0/24)不会加到系统路由表,ping/直接 ssh 10.11.21.x 不通;要访问 peer 服务只能走 port-forward。想要完整虚拟网需在有 TUN 支持的设备上跑 easytier。读取优先走 C 语言读取器,Python gpiod 只作回退。
C 二进制读取器:/root/dzxj_dtu/backend/scripts/dht11_reader
backend/scripts/dht11_reader.c(用 libgpiod C API,open-drain + 高速采样)gcc -O2 -o dht11_reader dht11_reader.c -lgpiod(设备已装 libgpiod-dev)dht11_reader [chip] [line],默认 gpiochip0 19{"valid":true,"humidity":43,"temperature":31,"raw":[...],"checksum":76}(温湿度为整数,无小数)module 'gpiod' has no attribute 'Chip' 或读到 0.0)Python gpiod 回退:backend/modules/dht11_sensor.py
gpiod 1.5.4,API 与系统 apt 的 python3-libgpiod 1.4.x 完全不同:
gpiod.Chip(...)(1.4.x) vs gpiod.chip(...)(1.5.x)gpiod.LINE_REQ_DIR_OUT vs gpiod.line_request.DIRECTION_OUTPUTline.request(consumer=..., type=...) vs line.request(type=...)(1.5.x 无 consumer 参数)close() 方法_gpiod_chip_class、常量映射),但优先靠 C 二进制,尽量别依赖这个回退。| 变量 | 默认 | 说明 |
|---|---|---|
DHT11_ENABLED |
true |
是否启用 |
DHT11_GPIO_PIN |
无 | GPIO line 号(设备上为19) |
DHT11_GPIO_CHIP |
gpiochip0 |
GPIO chip |
DHT11_POLL_INTERVAL |
5 |
读取间隔秒 |
DHT11_SIMULATE |
false |
是否模拟数据 |
DHT11_ENABLED=true 但未配 GPIO_PIN 且非模拟,会跳过传感器启动并打 warning。/root/dzxj_dtu/backend/scripts/dht11_reader gpiochip0 19
# 期望输出: {"valid":true,"humidity":xx,"temperature":xx,...}
journalctl -u dzxj_dtu | grep -E 'DHT11|环境传感器'
# 正常: "DHT11 本地传感器数据已处理: 温度=31.0°C, 湿度=43.0%"
:1883。xt.wenhq.top:8581。/root/dzxj_dtu/backend/mqtt_config.json:
/api/mqtt/connect 连接成功后自动 save_mqtt_config()。__main__ 里会 auto_connect_mqtt() 读取该文件自动重连。backend/app.py):save_mqtt_config() / load_mqtt_config() / auto_connect_mqtt() / mqtt_connect()(API /api/mqtt/connect)。backend/modules/mqtt_client.py(paho-mqtt==1.6.1,重连无限尝试,max_reconnect_attempts=0)。线架系统,DTU 协议主题格式:{topic_prefix}/{customer_id}/dtu/{dtu_id}/{topic}。/dev/ttyS8 @ 9600,连接配置持久化在 /root/dzxj_dtu/backend/serial_config.json。auto_connect_serial() 自动重连。backend/modules/modbus_rtu.py;串口封装在 backend/modules/serial_port.py。jumper_uid(前 4 位 DTU 号 + 后 12 位卡号),适配逻辑在 app.py 的 _to_mqtt_jumper_uid / _from_mqtt_jumper_uid。/root/dzxj_dtu/,后端在 backend/,前端构建产物在 backend/static/。/root/dzxj_dtu/venv/bin/python(依赖见 backend/requirements.txt,注意 gpiod 是 pip 1.5.4)。常用操作:
# 通过 frp 连上后
systemctl restart dzxj_dtu
journalctl -u dzxj_dtu -f
systemctl status frpc easytier mosquitto
更新代码后用 scp 覆盖对应文件再 systemctl restart dzxj_dtu。
本地工作目录 = 本仓库;改代码后注意同步到设备。
| 症状 | 排查 |
|---|---|
| SSH 连不上 149 | 先ping 192.168.199.149;再试 ssh -p 6000 root@127.0.0.1(frp stcp);若直接 IP 通但 6000 不通,查 systemctl status frpc |
| frpc 起不来 | journalctl -u frpc;注意 stcp 配置字段是 secretKey(不是 sk),老版本报 unknown field "sk" |
| 温湿度读到 0.0 或报 gpiod 错 | 确认dht11_reader 二进制存在且可执行;dht11_reader gpiochip0 19 手测 |
| easytier 组网后虚拟 IP 不通 | --no-tun 模式限制,虚拟 IP 不进路由表,只能走 port-forward |
| MQTT 重启后没自动连 | 确认/root/dzxj_dtu/backend/mqtt_config.json 存在;存在则看 auto_connect_mqtt 日志 |
--no-tun。secretKey,不是 sk(frp 0.70 报错)。123456(本机/测试环境)。app.py 后必须重启 dzxj_dtu 才生效。5001(Flask),前端由 nginx 提供 80 端口。