Explorar o código

docs: 完善README项目说明文档

steven_roc hai 4 días
pai
achega
2c9eee7784
Modificáronse 1 ficheiros con 405 adicións e 2 borrados
  1. 405 2
      README.md

+ 405 - 2
README.md

@@ -1,3 +1,406 @@
-# mppt_monitor
+# MPPT 太阳能充电控制器监控系统
 
-mppt_monitor
+基于 C 语言的 MPPT(最大功率点跟踪)太阳能充电控制器实时监控与数据采集系统。通过 **Modbus TCP** 采集设备运行数据,使用 **Mongoose** 提供 Web 仪表盘与 REST API,并将历史数据持久化到 **SQLite3**,支持多设备监控与远程参数下发。
+
+- 协议标准:DM 系列 ModBus 485 协议 V2.1(Modbus RTU over TCP)
+- 支持平台:Ubuntu 24.04(x86_64)/ 树莓派 5 8G(aarch64)
+- 当前版本:v2.4.0
+
+---
+
+## 目录
+
+- [功能特性](#功能特性)
+- [系统架构](#系统架构)
+- [目录结构](#目录结构)
+- [运行环境](#运行环境)
+- [快速开始](#快速开始)
+- [配置说明](#配置说明)
+- [Web 界面](#web-界面)
+- [REST API](#rest-api)
+- [Modbus 协议](#modbus-协议)
+- [数据库](#数据库)
+- [systemd 后台部署](#systemd-后台部署)
+- [文档索引](#文档索引)
+- [常见问题](#常见问题)
+- [许可证](#许可证)
+
+---
+
+## 功能特性
+
+- **实时数据采集**:每 2 秒轮询一次设备(可配置),读取电池电压、光伏电压、充电电流、功率、电量、温度、故障码、充电状态、设备类型等全部运行参数。
+- **多设备支持**:单网关下最多支持 16 台 MPPT 设备(地址 1~247),可在配置文件中指定设备地址列表。
+- **远程参数设置**:通过 Web 界面下发设备参数,自动适配 **FC 0x06(写单寄存器)** 与 **FC 0x10(写多寄存器)**,内置参数范围校验。
+- **历史数据存储**:按可配置间隔(默认 10 秒)将数据写入 SQLite3,支持数据保留周期自动清理。
+- **历史数据查询**:按时间范围查询,趋势图可视化 + 分页数据表格;默认查询区间为中国时区(UTC+8)前一天至今。
+- **Web 仪表盘**:实时监控、历史查询、设备设置三个标签页,响应式布局,浏览器直接访问。
+- **可靠连接**:10 秒连接/读写超时(可配置),断线自动重连;TCP 缓冲区残留清理,避免地址不匹配。
+- **Web 服务自愈**:HTTP 服务异常退出后自动重新监听,配合 systemd 实现进程级与线程级双重保障。
+- **并发安全**:互斥锁保护共享数据与 Socket 收发,串行化轮询线程与写入线程。
+
+---
+
+## 系统架构
+
+```
+┌──────────────────────────────────────────────────────────┐
+│                    mppt_monitor 进程                      │
+│                                                          │
+│  ┌──────────────┐   ┌──────────────┐   ┌──────────────┐ │
+│  │ Modbus 轮询  │   │  数据存储    │   │  信号处理    │ │
+│  │   线程       │   │    线程      │   │ SIGINT/TERM  │ │
+│  │  (2 秒/次)   │   │ (10 秒/次)   │   │  优雅退出    │ │
+│  └──────┬───────┘   └──────┬───────┘   └──────────────┘ │
+│         │                  │                             │
+│         ▼                  ▼                             │
+│  ┌────────────────────────────────┐    ┌──────────────┐ │
+│  │     共享数据 + sock_mutex      │    │  SQLite3 DB  │ │
+│  └────────────────────────────────┘    │ (WAL 模式)   │ │
+│         ▲                              └──────────────┘ │
+│         │ sock_mutex                                    │
+│  ┌──────┴───────────────────────────────────────────┐   │
+│  │        Mongoose HTTP 服务器(自愈线程)          │   │
+│  │   REST API   /   静态文件 www/index.html         │   │
+│  └──────────────────────────────────────────────────┘   │
+└───────────────────────────┬──────────────────────────────┘
+                            │ Modbus TCP (RTU over TCP)
+                            ▼
+              discover.zhonjin.com:40635
+                     (MPPT 设备网关)
+                            │
+            ┌───────────────┼───────────────┐
+            ▼               ▼               ▼
+        MPPT #1         MPPT #2   ...   MPPT #16
+```
+
+三个工作线程与一个 HTTP 事件循环:
+
+| 线程 | 职责 | 周期 |
+|------|------|------|
+| Modbus 轮询线程 | 连接/重连设备、读取 Input/Output 寄存器、更新共享数据 | 2 秒(可配置) |
+| 数据存储线程 | 将最新数据批量写入 SQLite,清理过期数据 | 10 秒(可配置) |
+| HTTP 事件循环 | 处理 REST 请求与静态页面,异常自动重启 | 事件驱动 |
+| 主线程 | 周期打印摘要、等待退出信号 | 10 秒 |
+
+---
+
+## 目录结构
+
+```
+mppt_monitor/
+├── src/                        # 应用源代码
+│   ├── main.c                  # 主程序:线程、信号处理、启动编排
+│   ├── modbus_client.h/.c      # Modbus TCP 客户端(CRC、读写、参数校验)
+│   ├── web_server.h/.c         # Mongoose HTTP 服务与 REST API
+│   ├── config.h/.c             # INI 配置文件解析
+│   └── db.h/.c                 # SQLite3 历史数据存储与查询
+├── www/
+│   └── index.html              # Web 仪表盘(Chart.js,单文件)
+├── lib/                        # 第三方库(随仓库提供,无需联网下载)
+│   ├── cJSON-1.7.19/           # cJSON 1.7.19
+│   └── mongoose-7.23/          # Mongoose 7.23
+├── config.ini                  # 运行时配置文件
+├── Makefile                    # 构建脚本
+├── INSTALL.md                  # 快速安装指南
+├── CHANGELOG.md                # 变更日志(持续更新)
+├── TECHNICAL.md                # 技术方案文档(持续更新)
+└── FAQ.md                      # 问答归档(持续更新)
+```
+
+> 说明:本仓库根目录的 `README.md`、`LICENSE`、`.gitignore` 为仓库级文件;实际工程位于 `mppt_monitor/` 子目录。
+
+---
+
+## 运行环境
+
+### 硬件
+
+- 主机:PC / 工控机 / 树莓派 5(建议 4GB 以上内存)
+- 被控设备:DM 系列 MPPT 太阳能充电控制器(经 Modbus TCP 网关接入)
+- 网络:主机需能访问设备网关地址与端口
+
+### 软件
+
+- 操作系统:Ubuntu 24.04 LTS 或 Raspberry Pi OS(64 位)
+- 编译器:GCC(支持 C11)
+- 构建工具:GNU Make
+- 依赖库:SQLite3(运行库 + 开发头文件)
+- 可选:OpenSSL 3.x(TLS 支持,构建时自动探测)
+- 浏览器:Chrome / Edge / Firefox(用于访问仪表盘)
+
+---
+
+## 快速开始
+
+### 1. 安装依赖
+
+**Ubuntu 24.04:**
+
+```bash
+sudo apt-get update
+sudo apt-get install -y build-essential make libsqlite3-dev pkg-config
+# 可选 OpenSSL
+sudo apt-get install -y libssl-dev
+```
+
+**树莓派 5(Raspberry Pi OS 64 位):**
+
+```bash
+sudo apt-get update
+sudo apt-get install -y build-essential make libsqlite3-dev pkg-config libssl-dev
+```
+
+### 2. 获取代码并编译
+
+```bash
+git clone https://git.zhonjin.com:40717/steven_roc/mppt_monitor.git
+cd mppt_monitor/mppt_monitor          # 工程目录
+make
+```
+
+构建产物为 `build/mppt_monitor`。第三方库(cJSON、Mongoose)已随仓库提供,无需联网下载。
+
+常用构建命令:
+
+```bash
+make            # 编译
+make clean      # 清理构建产物
+make run        # 编译并运行
+make debug      # 带调试符号与 AddressSanitizer
+```
+
+### 3. 修改配置
+
+按需编辑 `config.ini`(主要确认设备地址、网关地址、Web 端口)。默认配置:
+
+- 网关:`discover.zhonjin.com:40635`
+- 设备地址:`1`
+- 轮询间隔:2 秒
+- Web 端口:`8085`
+
+### 4. 运行
+
+```bash
+./build/mppt_monitor
+```
+
+启动后浏览器访问:
+
+```
+http://<主机IP>:8085
+```
+
+> 若设置了环境变量 `DEPLOY_RUN_PORT`,Web 端口会以该变量为准(用于沙箱/容器部署)。
+
+---
+
+## 配置说明
+
+配置文件 `config.ini` 采用 INI 格式,分节如下:
+
+```ini
+[modbus]
+host = discover.zhonjin.com      # 设备网关域名或 IP
+port = 40635                     # 网关端口
+timeout_sec = 10                 # 连接 / 读写超时(秒)
+poll_interval_sec = 2            # 轮询间隔(秒)
+
+[storage]
+db_path = mppt_data.db           # SQLite 数据库文件路径
+interval_sec = 10                # 历史数据存储间隔(秒)
+retention_days = 365             # 数据保留天数(超过自动清理,0 表示永久)
+
+[server]
+port = 8085                      # Web 服务端口(DEPLOY_RUN_PORT 优先)
+page_size = 20                   # 历史查询默认每页条数
+
+[devices]
+device_addrs = 1                 # 设备地址列表,逗号分隔,如 1,2,3
+```
+
+修改配置后需重启程序生效。
+
+---
+
+## Web 界面
+
+浏览器访问 `http://<主机IP>:8085`,包含三个标签页:
+
+1. **实时监控(Real-time Monitor)**
+   - 展示各设备电池电压、光伏电压、充电电流、功率、电量、温度、充电状态、故障码等
+   - 数据按轮询周期自动刷新
+2. **历史查询(History Query)**
+   - 日期时间范围选择器,默认中国时区前一天至今
+   - Chart.js 趋势曲线 + 分页数据表格
+3. **设备设置(Device Settings)**
+   - 选择设备与参数,输入值后下发
+   - 提交前做参数范围校验,写入结果即时提示
+
+---
+
+## REST API
+
+所有接口返回 `application/json`,并支持 CORS(跨域访问)。
+
+| 方法 | 路径 | 说明 |
+|------|------|------|
+| GET | `/api/health` | 健康检查(服务存活、连接状态) |
+| GET | `/api/status` | 系统运行状态汇总 |
+| GET | `/api/data` | 所有设备最新实时数据 |
+| GET | `/api/devices` | 已配置设备列表 |
+| GET | `/api/settings?device_addr=&param=` | 查询指定设备指定参数当前值 |
+| POST | `/api/settings` | 下发设备参数 |
+| GET | `/api/history` | 历史数据分页查询 |
+| GET | `/api/history/stats` | 历史数据统计信息 |
+
+### 查询历史数据
+
+```
+GET /api/history?device_addr=1&start=<unix秒>&end=<unix秒>&page=1&page_size=20
+```
+
+### 下发参数
+
+```bash
+curl -X POST http://<主机IP>:8085/api/settings \
+  -H 'Content-Type: application/json' \
+  -d '{"device_addr": 1, "param": "battery_type", "value": 4}'
+```
+
+请求字段:
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `device_addr` | number | 是 | 设备地址(1~247) |
+| `param` | string | 是 | 参数标识(见协议寄存器映射) |
+| `value` | number | 是 | 目标值 |
+
+成功响应:
+
+```json
+{"success": true, "device_addr": 1, "param": "battery_type", "value": 4}
+```
+
+失败响应:
+
+```json
+{"success": false, "error": "错误原因"}
+```
+
+---
+
+## Modbus 协议
+
+- 传输方式:Modbus RTU over TCP(RTU 帧封装在 TCP 连接上,帧尾带 CRC-16)
+- 校验:CRC-16/Modbus(多项式 0xA001,初值 0xFFFF,低字节在前)
+- 功能码:
+
+| 功能码 | 用途 |
+|--------|------|
+| 0x04 | 读 Input Register(运行数据,只读) |
+| 0x03 | 读 Holding/Output Register(可设置参数) |
+| 0x06 | 写单个 Holding Register(单参数下发,优先使用) |
+| 0x10 | 写多个 Holding Register(设备不支持 0x06 时回退) |
+
+示例(读 10 个 Input 寄存器,设备地址 1):
+
+```
+请求:01 04 00 00 00 0A 70 0D
+响应:01 04 14 01 0C 01 81 00 10 00 07 00 2E 00 14 00 60 00 02 00 01 00 3C E9 F1
+```
+
+完整寄存器地址表、读写格式、异常码与参数取值范围详见 **TECHNICAL.md** 与协议文档。
+
+**写寄存器双通道自适应策略:**
+
+1. 优先发送 FC 0x06(写单寄存器,响应为请求回显,共 8 字节);
+2. 若设备回异常码"功能不支持 / 地址非法",再回退 FC 0x10(写多寄存器,正常响应 8 字节);
+3. 每条指令前保留总线空闲间隔,配合 `sock_mutex` 串行化,避免帧交错。
+
+---
+
+## 数据库
+
+- 引擎:SQLite3,单文件(默认 `mppt_data.db`)
+- 模式:开启 **WAL**(Write-Ahead Logging),提升并发读写性能
+- 优化:在时间与设备地址字段建立索引
+- 维护:按 `retention_days` 自动清理过期数据
+
+历史记录表按"设备地址 + 时间戳"存储每次采集的全部参数,供趋势图与分页查询使用。详细表结构见 **TECHNICAL.md**。
+
+---
+
+## systemd 后台部署
+
+生产环境建议用 systemd 管理进程,实现开机自启与异常自动重启。
+
+1. 创建服务文件 `/etc/systemd/system/mppt-monitor.service`:
+
+```ini
+[Unit]
+Description=MPPT Solar Charge Controller Monitor
+After=network-online.target
+Wants=network-online.target
+
+[Service]
+Type=simple
+WorkingDirectory=/opt/mppt_monitor
+ExecStart=/opt/mppt_monitor/build/mppt_monitor
+Restart=always
+RestartSec=5
+Environment=DEPLOY_RUN_PORT=8085
+
+[Install]
+WantedBy=multi-user.target
+```
+
+2. 部署并启用:
+
+```bash
+sudo cp -r . /opt/mppt_monitor
+sudo systemctl daemon-reload
+sudo systemctl enable --now mppt-monitor
+sudo systemctl status mppt-monitor
+journalctl -u mppt-monitor -f          # 查看日志
+```
+
+> 树莓派部署的完整步骤(含系统烧录、网络、防火墙、时区配置)见 **TECHNICAL.md** 树莓派章节。
+
+---
+
+## 文档索引
+
+工程目录 `mppt_monitor/` 下提供以下持续更新文档:
+
+| 文档 | 内容 |
+|------|------|
+| [INSTALL.md](mppt_monitor/INSTALL.md) | 快速安装与运行指南 |
+| [CHANGELOG.md](mppt_monitor/CHANGELOG.md) | 版本变更与每次 bug 修复详细说明 |
+| [TECHNICAL.md](mppt_monitor/TECHNICAL.md) | 完整技术方案:架构、协议、API、数据库、编译配置、Ubuntu/树莓派/Docker 部署、故障排查 |
+| [FAQ.md](mppt_monitor/FAQ.md) | 历史问题与排查结论归档,按分类累计追加 |
+
+---
+
+## 常见问题
+
+- **写入提示 "Empty request body"**:已在新版本修复。POST 需携带合法 JSON 与 `Content-Type: application/json`;新版本含 body 解析回退机制。
+- **写入一直失败**:新版本默认使用 FC 0x06 并在需要时回退 FC 0x10,兼容更多固件;请同时确认参数值在允许范围内。
+- **读不到数据 / 连接被立即断开**:优先排查网络可达性与服务端 **IP 白名单/授权**。可在主机上执行 `nc -vz discover.zhonjin.com 40635` 检测端口;若 TCP 能连但秒断,多为访问授权限制。
+- **历史数据查不到**:确认存储间隔配置、数据库路径可写,并确认查询时间范围内程序在持续运行。
+- **编译报 `sqlite3.h: No such file`**:安装开发包 `sudo apt-get install libsqlite3-dev`。
+
+更多排查步骤见 [FAQ.md](mppt_monitor/FAQ.md)。
+
+---
+
+## 许可证
+
+详见 [LICENSE](LICENSE)。
+
+第三方组件版权归各自所有者:
+
+- cJSON 1.7.19
+- Mongoose 7.23(注意其商用授权条款)
+- SQLite3(公有领域)
+- Chart.js(用于 Web 仪表盘)