本文档持续更新,记录 MPPT Monitor 的完整技术架构、协议细节、API 设计。
| 组件 | 规格 | 说明 |
|---|---|---|
| 主板 | Raspberry Pi 5 8GB | BCM2712 四核 Cortex-A76 @ 2.4GHz |
| 存储 | microSD 卡 ≥32GB 或 NVMe SSD | 推荐 SSD 提升数据库写入性能 |
| 电源 | 官方 27W USB-C 电源 | 确保稳定供电 |
| 网络 | 以太网 或 Wi-Fi | 用于连接 Modbus 设备和 Web 访问 |
| 散热 | 主动散热风扇 | 长时间运行必备 |
下载镜像
# 从 Ubuntu 官网下载 Raspberry Pi 专用镜像
wget https://cdimage.ubuntu.com/releases/24.04/release/ubuntu-24.04.1-preinstalled-server-arm64+raspi.img.xz
烧录镜像
# 使用 Raspberry Pi Imager 或 dd 命令
sudo dd if=ubuntu-24.04.1-preinstalled-server-arm64+raspi.img.xz of=/dev/sdX bs=4M status=progress
首次启动配置
# 连接显示器和键盘,或通过网络 SSH 登录
# 默认用户名/密码:ubuntu/ubuntu
# 首次登录会要求修改密码
# 使用 Raspberry Pi Imager 选择 Raspberry Pi OS (64-bit)
# 或手动下载:https://www.raspberrypi.com/software/operating-systems/
# 1. 更新系统
sudo apt update && sudo apt upgrade -y
# 2. 设置时区(中国)
sudo timedatectl set-timezone Asia/Shanghai
# 3. 设置主机名
sudo hostnamectl set-hostname mppt-monitor
# 4. 配置静态 IP(可选,编辑 /etc/netplan/01-netcfg.yaml)
# network:
# version: 2
# ethernets:
# eth0:
# dhcp4: no
# addresses: [192.168.1.100/24]
# gateway4: 192.168.1.1
# nameservers:
# addresses: [8.8.8.8, 114.114.114.114]
# 5. 重启
sudo reboot
# 基础编译工具
sudo apt install -y build-essential gcc make
# SQLite3 开发库
sudo apt install -y libsqlite3-dev
# OpenSSL 开发库(可选,用于 HTTPS)
sudo apt install -y libssl-dev
# 验证安装
gcc --version
sqlite3 --version
pkg-config --libs openssl # 如果安装了 OpenSSL
# 1. 传输项目文件到树莓派
# 方式一:SCP
scp -r mppt_monitor/ ubuntu@192.168.1.100:~/
# 方式二:Git
git clone <your-repo-url> ~/mppt_monitor
# 2. 进入项目目录
cd ~/mppt_monitor
# 3. 编译
make clean && make
# 4. 验证编译结果
ls -la build/mppt_monitor
file build/mppt_monitor
# 应显示:ELF 64-bit LSB executable, ARM aarch64
# 编辑配置文件
nano config.ini
[modbus]
host = discover.zhonjin.com
port = 40635
timeout_sec = 10
reconnect_interval_sec = 2
[devices]
# 设备地址列表(逗号分隔,1-247)
addresses = 1
[storage]
# 数据存储间隔(秒)
interval_sec = 10
# 数据库文件路径
db_path = mppt_data.db
[web]
# Web 服务端口
port = 8085
# 历史数据分页大小
page_size = 20
# 方式一:直接运行(调试用)
./build/mppt_monitor
# 方式二:后台运行
nohup ./build/mppt_monitor > /var/log/mppt_monitor.log 2>&1 &
# 方式三:systemd 服务(推荐生产环境)
sudo make systemd
sudo systemctl enable mppt-monitor
sudo systemctl start mppt-monitor
# 查看服务状态
sudo systemctl status mppt-monitor
# 查看日志
sudo journalctl -u mppt-monitor -f
# 创建服务文件
sudo tee /etc/systemd/system/mppt-monitor.service << 'EOF'
[Unit]
Description=MPPT Solar Monitor - DM Series
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/mppt_monitor
ExecStart=/home/ubuntu/mppt_monitor/build/mppt_monitor
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
# 安全加固
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/home/ubuntu/mppt_monitor
[Install]
WantedBy=multi-user.target
EOF
# 重载 systemd
sudo systemctl daemon-reload
# 启用并启动服务
sudo systemctl enable mppt-monitor
sudo systemctl start mppt-monitor
# 如果使用 UFW 防火墙
sudo ufw allow 8085/tcp # Web 服务端口
sudo ufw allow 22/tcp # SSH(如果还没开放)
sudo ufw enable
# 设置 CPU 性能模式为 performance
sudo apt install -y cpufrequtils
echo 'GOVERNOR="performance"' | sudo tee /etc/default/cpufrequtils
sudo systemctl restart cpufrequtils
# SQLite3 性能优化(在 db.c 中已配置)
# - WAL 模式:允许读写并发
# - 同步模式:NORMAL(平衡性能和安全性)
# - 缓存大小:2000 页
# 优化 TCP 参数(/etc/sysctl.d/99-mppt.conf)
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5
net.core.somaxconn = 1024
# 应用配置
sudo sysctl -p /etc/sysctl.d/99-mppt.conf
# 服务状态
sudo systemctl status mppt-monitor
# 实时日志
sudo journalctl -u mppt-monitor -f --since "1 hour ago"
# 资源使用
top -p $(pgrep mppt_monitor)
# 查看数据库大小
ls -lh ~/mppt_monitor/mppt_data.db
# 查看记录数
sqlite3 ~/mppt_monitor/mppt_data.db "SELECT COUNT(*) FROM history_data;"
# 清理旧数据(保留最近 30 天)
sqlite3 ~/mppt_monitor/mppt_data.db "DELETE FROM history_data WHERE created_at < datetime('now', '-30 days');"
# 数据库优化
sqlite3 ~/mppt_monitor/mppt_data.db "VACUUM;"
# 创建备份脚本
cat << 'EOF' > ~/mppt_monitor/backup.sh
#!/bin/bash
BACKUP_DIR="/home/ubuntu/backups"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
cp ~/mppt_monitor/mppt_data.db "$BACKUP_DIR/mppt_data_$DATE.db"
# 保留最近 7 天的备份
find $BACKUP_DIR -name "mppt_data_*.db" -mtime +7 -delete
EOF
chmod +x ~/mppt_monitor/backup.sh
# 添加 cron 定时任务(每天凌晨 2 点备份)
crontab -e
# 添加:0 2 * * * /home/ubuntu/mppt_monitor/backup.sh
# 检查端口占用
sudo ss -tuln | grep 8085
# 检查日志
sudo journalctl -u mppt-monitor -n 100
# 手动运行查看错误
./build/mppt_monitor
# 测试网络连通性
ping discover.zhonjin.com
# 测试端口连通性
nc -zv discover.zhonjin.com 40635
# 检查 DNS 解析
nslookup discover.zhonjin.com
# 检查数据库锁
sqlite3 ~/mppt_monitor/mppt_data.db "PRAGMA busy_timeout = 5000;"
# 如果数据库损坏,尝试恢复
sqlite3 ~/mppt_monitor/mppt_data.db ".recover" > recovered.sql
# 1. 停止服务
sudo systemctl stop mppt-monitor
# 2. 备份数据
cp ~/mppt_monitor/mppt_data.db ~/mppt_monitor/mppt_data.db.backup
# 3. 拉取新代码
cd ~/mppt_monitor
git pull
# 4. 重新编译
make clean && make
# 5. 启动服务
sudo systemctl start mppt-monitor
# 6. 验证
curl http://localhost:8085/api/health
| 组件 | 最低配置 | 推荐配置 |
|---|---|---|
| CPU | 双核 2.0GHz | 四核 3.0GHz+ |
| 内存 | 2GB | 4GB+ |
| 存储 | 10GB | SSD 50GB+ |
| 网络 | 100Mbps | 1Gbps |
# 1. 安装 Ubuntu 24.04 Server
# 从 https://ubuntu.com/download/server 下载 ISO
# 2. 安装依赖
sudo apt update && sudo apt upgrade -y
sudo apt install -y build-essential gcc make libsqlite3-dev libssl-dev
# 3. 编译项目
cd ~/mppt_monitor
make clean && make
# 4. 运行服务
sudo make systemd
sudo systemctl enable mppt-monitor
sudo systemctl start mppt-monitor
# Dockerfile
FROM ubuntu:24.04
RUN apt update && apt install -y \
build-essential gcc make libsqlite3-dev \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY . .
RUN make clean && make
EXPOSE 8085
CMD ["./build/mppt_monitor"]
# 构建和运行
docker build -t mppt-monitor .
docker run -d --name mppt -p 8085:8085 -v $(pwd)/data:/app mppt-monitor
开发一个轻量级 C 语言嵌入式监控程序,通过 Modbus RTU over TCP 协议读取 MPPT 太阳能充电控制器的实时数据,并通过 HTTP REST API 对外提供 JSON 格式的实时数据接口。支持历史数据定时存储到 SQLite3 数据库,并提供带趋势图表的历史数据查询页面。
┌─────────────────────────────────────────────────────────┐
│ MPPT Monitor │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Modbus TCP │ │ Mongoose HTTP│ │
│ │ Client │ │ Server :8085 │ │
│ │ (Thread) │ │ (Main Thread)│ │
│ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────────────────────────┐ │
│ │ Shared Data (mppt_data_t) │ │
│ │ Protected by pthread_mutex │ │
│ └──────────┬───────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────┐ │
│ │ SQLite3 Database │ │
│ │ (历史数据存储) │ │
│ └──────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────────┐
│ MPPT Device │ │ Web Browser / │
│ TCP:40635 │ │ REST Client │
└─────────────┘ └─────────────────┘
| 线程 | 职责 | 说明 |
|---|---|---|
| Main Thread | Mongoose HTTP 事件循环 | 处理 HTTP 请求、Web 服务器看门狗 |
| Modbus Thread | Modbus 数据采集 | 每 2 秒读取一次寄存器,自动重连 |
| 参数 | 值 |
|---|---|
| 协议 | Modbus RTU over TCP(原始 TCP Socket) |
| 目标地址 | discover.zhonjin.com |
| 目标端口 | 40635 |
| 从机地址 | 0x01 |
| 功能码 | 0x04(读输入寄存器) |
| 起始寄存器 | 0x0000(对应 30001) |
| 寄存器数量 | 10(30001~30010) |
| 超时时间 | 10 秒 |
| 轮询间隔 | 2000ms |
发→ 01 04 00 00 00 0A 70 0D
字节解析:
01 - 从机地址 (Slave Address)
04 - 功能码: 读输入寄存器 (Read Input Registers)
00 00 - 起始寄存器地址 (0x0000 = 30001)
00 0A - 寄存器数量 (10个)
70 0D - CRC-16 校验 (低字节在前)
收← 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
字节解析:
01 - 从机地址
04 - 功能码
14 - 数据长度 (20字节 = 10个寄存器 × 2字节)
01 0C - 寄存器1: 电池电压 (268 → 26.8V)
01 81 - 寄存器2: 光伏电压 (385 → 38.5V)
00 10 - 寄存器3: 光伏充电电流 (16 → 1.6A)
00 07 - 寄存器4: 累计发电量 (7 → 0.7kWh)
00 2E - 寄存器5: 机器温度 (46 → 46°C)
00 14 - 寄存器6: 故障代码 (20 → 正常)
00 60 - 寄存器7: 电池电量 (96 → 96%)
00 02 - 寄存器8: 电池串数 (2)
00 01 - 寄存器9: 充电状态 (1 → 充电中)
00 3C - 寄存器10: 设备类型 (60)
E9 F1 - CRC-16 校验
| 寄存器 | 地址 | 参数名 | 原始值 | 实际值 | 单位 | 说明 |
|---|---|---|---|---|---|---|
| 30001 | 0x0000 | 电池电压 | raw/10 | V | 24V系统正常范围 20-30V | |
| 30002 | 0x0001 | 光伏电压 | raw/10 | V | 光伏板输出电压 | |
| 30003 | 0x0002 | 光伏充电电流 | raw/10 | A | 当前充电电流 | |
| 30004 | 0x0003 | 累计发电量 | raw/10 | kWh | 历史总发电量 | |
| 30005 | 0x0004 | 机器温度 | raw | °C | 控制器温度 | |
| 30006 | 0x0005 | 故障代码 | raw | - | 0/20=正常 | |
| 30007 | 0x0006 | 电池电量 | raw | % | SOC 百分比 | |
| 30008 | 0x0007 | 电池串数 | raw | - | 保留字段 | |
| 30009 | 0x0008 | 充电状态 | raw | - | 0=空闲 1=充电 2=吸收 3=浮充 | |
| 30010 | 0x0009 | 设备类型 | raw | - | 设备型号代码 |
多项式: 0xA001 (0x8005 的反转)
初始值: 0xFFFF
字节序: 低字节在前 (Little-Endian on wire)
算法流程:
1. 初始化 CRC = 0xFFFF
2. 对每个字节:
a. CRC ^= byte
b. 循环 8 次:
- 如果 CRC 最低位为 1: CRC = (CRC >> 1) ^ 0xA001
- 否则: CRC >>= 1
3. 返回 CRC 值
| 参数 | 值 |
|---|---|
| 监听地址 | 0.0.0.0 |
| 监听端口 | 8085 |
| HTTP 库 | Mongoose 7.22 |
| JSON 库 | cJSON 1.7.19 |
响应示例:
{
"timestamp": "2026-08-04T15:30:00",
"data_valid": true,
"battery": {
"voltage": 26.8,
"soc": 96,
"string_count": 2
},
"pv": {
"voltage": 38.5,
"current": 1.6,
"power": 61.6
},
"cumulative_energy_kwh": 0.7,
"device": {
"temperature": 46.0,
"fault_code": 20,
"fault_desc": "Normal",
"charge_state": 1,
"charge_state_desc": "Charging (Bulk)",
"device_type": 60
},
"raw_registers": [268, 385, 16, 7, 46, 20, 96, 2, 1, 60]
}
响应示例:
{
"connection": {
"state": "connected",
"host": "discover.zhonjin.com",
"port": 40635,
"reconnect_count": 0
},
"device_online": true,
"consecutive_failures": 0,
"last_update": "2026-08-04T15:30:00"
}
响应:
{"status": "ok"}
返回内嵌的 HTML 仪表盘页面,每 2 秒自动刷新数据。
| 旧 API (7.x 早期) | 新 API (7.22) | 说明 |
|---|---|---|
mg_http_match_uri(hm, "/path") |
mg_match(hm->uri, mg_str("/path"), NULL) |
URI 匹配 |
struct mg_str { const char *ptr; size_t len; } |
struct mg_str { char *buf; size_t len; } |
字符串结构体 |
hm->uri.ptr |
hm->uri.buf |
访问字符串数据 |
URI 匹配: 使用 mg_match() 替代 mg_http_match_uri()
// 旧方式(已废弃)
if (mg_http_match_uri(hm, "/api/data")) { ... }
// 新方式(mongoose-7.22)
if (mg_match(hm->uri, mg_str("/api/data"), NULL)) { ... }
字符串结构体: ptr 改为 buf
// 旧方式
const char *data = hm->uri.ptr;
// 新方式
char *data = hm->uri.buf;
通配符匹配: 支持 ?(单字符)、*(不含/)、#(含/)
// 匹配 /api/ 下所有路径
mg_match(hm->uri, mg_str("/api/#"), NULL)
连接失败 → 等待 2 秒 → 重试
读取超时 → 记录失败计数
连续 3 次失败 → 断开连接 → 重新建立连接
DNS 解析失败 → 等待后重试
主循环每 5 秒检查一次 Web 服务器状态
如果监听连接丢失 → 自动重新启动 HTTP 监听
SIGPIPE 信号被忽略 → 防止客户端断开导致进程退出
Modbus 线程写入数据时使用 pthread_mutex 保护
Web 线程读取数据时加锁读取
确保 HTTP 响应中的数据不会在序列化过程中被修改
Web 设备参数设置(POST /api/settings → modbus_write_register())与
Modbus 轮询线程共用同一个 TCP Socket。为避免帧交错导致的写入失败/数据错乱,
采用如下并发模型:
┌─────────────────────────────────────────────────────────────┐
│ sock_mutex (pthread_mutex_t) 串行化所有 Socket 收发操作 │
├─────────────────────────────────────────────────────────────┤
│ 轮询线程: read_input/read_output → modbus_send_recv() │
│ (内部加锁: drain → send → recv → 解锁) │
│ 写入线程: modbus_write_register() │
│ (加锁: drain → send(frame) → recv(resp) → 解锁) │
└─────────────────────────────────────────────────────────────┘
关键点:
data_mutex 负责设备数据快照的读写一致性,与 sock_mutex 职责分离,避免死锁。Modbus 功能码 0x10(写多个寄存器)的正常响应帧为 8 字节:
| 字节 | 内容 | 说明 |
|---|---|---|
| 0 | 设备地址 | 回显请求地址 |
| 1 | 功能码 0x10 |
写多个寄存器 |
| 2-3 | 起始地址 | 回显写入的起始寄存器地址 |
| 4-5 | 寄存器数量 | 回显写入的数量(本系统为 1) |
| 6-7 | CRC-16 | 前 6 字节 CRC |
异常响应帧为 5 字节(地址 + 0x90 + 异常码 + CRC-2)。
⚠️ Bug 历史:v2.3.2 及以前版本将正常响应错误地按 6 字节解析, 并把"寄存器数量(0x00,0x01)"误当成 CRC 校验,导致每次写入都必然 CRC 失败 (Web 设置恒报"写入失败")。v2.3.3 已修复为按 8 字节规范解析。
Web 设置写入的单个参数,统一通过 modbus_write_register(),按下列顺序自适应选择功能码:
POST /api/settings
│
▼
参数范围校验 modbus_validate_setting()
│
▼
① FC 0x06 写单个寄存器
请求 8B: [addr][06][regHi][regLo][valHi][valLo][CRClo][CRChi]
响应 8B: 原样回显 + CRC
├─ 成功(功能码=0x06、地址/值回显正确、CRC 正确)→ 返回成功
├─ 异常码 0x01(功能不支持)/0x02(地址非法) → 进入 ②
└─ 超时 / 其他异常 → 直接报错,不盲目重试
│
▼
② FC 0x10 写多个寄存器(数量=1)
请求 13B / 响应 8B(见 5.5)
| 功能码 | 名称 | 请求长 | 响应长 | 适用 |
|---|---|---|---|---|
0x06 |
Write Single Register | 8B | 8B | 首选,单参数写入,兼容性最好 |
0x10 |
Write Multiple Registers | 13B | 8B | 回退方案,仅当设备不支持 0x06 |
设计理由:大量 DM 系列 / 低端 MPPT 固件对单参数只接受 FC 0x06, 对 0x10 回异常或静默不回。v2.4.0 之前固定 0x10 是部分设备写入失败的根因。
HTTP 服务运行在独立线程,内部为"监听 → mg_http_listen 事件循环 → 异常退出 → 等待 → 重新监听"的循环;
即使监听失败或事件循环异常返回,也会自动重试,保证 Web 服务长期在线。
应用整体仍由 systemd 托管(见树莓派章节),形成"进程级 + 线程级"双重保障。
| 指标 | 值 | 说明 |
|---|---|---|
| 数据采集间隔 | 2 秒 | 可通过 MODBUS_POLL_MS 调整 |
| HTTP 响应延迟 | < 1ms | 纯内存数据,无磁盘 IO |
| 内存占用 | ~2MB | 含 Mongoose 缓冲区 |
| CPU 占用 | < 1% | 空闲时几乎不消耗 CPU |
| 网络开销 | ~30 bytes/2s | Modbus 请求/响应 |
[modbus]
host = discover.zhonjin.com
port = 40635
slave_addr = 0x01
timeout_sec = 10
poll_ms = 2000
[storage]
interval_sec = 10
db_path = mppt_data.db
[web]
port = 8085
page_size = 50
| 配置段 | 键 | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
| modbus | host | string | discover.zhonjin.com | Modbus 设备域名/IP |
| modbus | port | int | 40635 | Modbus TCP 端口 |
| modbus | slave_addr | hex | 0x01 | Modbus 从机地址 |
| modbus | timeout_sec | int | 10 | 连接超时(秒) |
| modbus | poll_ms | int | 2000 | 轮询间隔(毫秒) |
| storage | interval_sec | int | 10 | 数据存储间隔(秒) |
| storage | db_path | string | mppt_data.db | SQLite 数据库文件路径 |
| web | port | int | 8085 | HTTP 服务端口 |
| web | page_size | int | 50 | 历史数据默认分页大小 |
0x 前缀(如 slave_addr = 0x01)使用 SQLite3 作为轻量级嵌入式数据库,无需额外服务进程。
CREATE TABLE IF NOT EXISTS history_data (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp INTEGER NOT NULL, -- Unix 时间戳
battery_voltage REAL NOT NULL, -- 电池电压 (V)
pv_voltage REAL NOT NULL, -- 光伏电压 (V)
pv_charge_current REAL NOT NULL, -- 光伏充电电流 (A)
cumulative_energy REAL NOT NULL, -- 累计发电量 (kWh)
machine_temp REAL NOT NULL, -- 机器温度 (°C)
fault_code INTEGER NOT NULL, -- 故障代码
battery_soc INTEGER NOT NULL, -- 电池电量 (%)
battery_string INTEGER NOT NULL, -- 电池串数
charge_state INTEGER NOT NULL, -- 充电状态
device_type INTEGER NOT NULL, -- 设备类型
pv_input_power REAL NOT NULL, -- 光伏输入功率 (W)
created_at TEXT DEFAULT (datetime('now', 'localtime'))
);
CREATE INDEX IF NOT EXISTS idx_history_timestamp ON history_data(timestamp);
Modbus 读取成功 → 更新共享数据 → 检查存储间隔
│
┌───────────────┴───────────────┐
│ 距上次存储 >= interval_sec? │
│ │
▼ Yes ▼ No
插入 SQLite 跳过
更新 last_store_time
GET /api/history
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| start_time | string | 否 | 起始时间,格式 YYYY-MM-DDTHH:MM:SS 或 YYYY-MM-DD HH:MM:SS |
| end_time | string | 否 | 结束时间,格式同上 |
| page | int | 否 | 页码,默认 1 |
| page_size | int | 否 | 每页条数,默认取 config.web.page_size,最大 500 |
| sort | string | 否 | 排序方式:ASC 或 DESC(默认) |
响应示例:
{
"total": 150,
"page": 1,
"page_size": 50,
"total_pages": 3,
"records": [
{
"id": 150,
"timestamp": "2026-08-04 16:30:00",
"timestamp_unix": 1785832200,
"battery_voltage": 26.8,
"pv_voltage": 37.2,
"pv_charge_current": 2.2,
"pv_input_power": 81.84,
"cumulative_energy": 0.8,
"machine_temp": 45,
"fault_code": 20,
"fault_desc": "Normal",
"battery_soc": 96,
"charge_state": 1,
"charge_state_desc": "Charging (Bulk)",
"device_type": 60
}
]
}
| 方面 | 措施 |
|---|---|
| 网络隔离 | Modbus TCP 仅出站连接,不监听外部端口 |
| HTTP 访问 | 当前无认证,建议通过反向代理添加 Basic Auth |
| 数据完整性 | Modbus CRC-16 校验确保数据正确性 |
| 异常输入 | HTTP 路由严格匹配,未匹配返回 404 |
| 内存安全 | 使用 cJSON 安全 API,无缓冲区溢出风险 |
| SQL 注入 | 使用 SQLite3 参数化查询(? 占位符),杜绝注入风险 |
| 配置安全 | config.ini 解析使用 snprintf 防溢出,非法值回退默认 |
| PLC地址 | 寄存器地址 | 寄存器名 | 值范围 | 换算 | 说明 |
|---|---|---|---|---|---|
| 30001 | 0x0000 | 电池电压 | 0-65535 | 1=0.1V | 实时电池电压 |
| 30002 | 0x0001 | 光伏电压 | 0-65535 | 1=0.1V | 光伏板输入电压 |
| 30003 | 0x0002 | 光伏充电电流 | 0-65535 | 1=0.1A | 当前充电电流 |
| 30004 | 0x0003 | 累计发电量 | 0-65535 | 1=0.1KWH | 总发电量 |
| 30005 | 0x0004 | 机器温度 | 0-255 | 1=1°C | 0xFF=故障 |
| 30006 | 0x0005 | 故障代码 | 0-255 | 见下表 | 设备故障状态 |
| 30007 | 0x0006 | 电池电量 | 0-100 | % | SOC |
| 30008 | 0x0007 | 电池串数 | 0-8 | 保留 | |
| 30009 | 0x0008 | 充电状态 | 0-1 | 0=未充电,1=充电 | |
| 30010 | 0x0009 | 设备类型 | 0-255 | 设备型号代码 | |
| 30011 | 0x000A | 软件版本 | 0-255 | 固件版本号 |
| PLC地址 | 寄存器地址 | 寄存器名 | 值范围 | 换算 | 读写 | 说明 |
|---|---|---|---|---|---|---|
| 40001 | 0x0000 | 电池类型 | 0-5 | 见下表 | R/W | |
| 40002 | 0x0001 | 电池等级 | 0-6 | 见下表 | R/W | |
| 40003 | 0x0002 | 光伏充电电流限制 | 5-100 | % | R/W | |
| 40004 | 0x0003 | 电池过放电压 | 80-600 | 1=0.1V | 只读 | |
| 40005 | 0x0004 | 电池提升电压 | 80-600 | 1=0.1V | R/W | |
| 40006 | 0x0005 | 电池充满电压 | 80-600 | 1=0.1V | R/W | |
| 40007 | 0x0006 | 过放恢复电压 | 80-600 | 1=0.1V | 只读 | |
| 40008 | 0x0007 | 设备485地址 | 0-247 | R/W | ||
| 40009 | 0x0008 | 充电运行模式 | 0-1 | 0=MPPT,1=DCDC | R/W |
| 值 | 类型 | 提升电压 | 过充电压 | 恢复电压 | 过放电压 |
|---|---|---|---|---|---|
| 0 | 胶体电池 | 14.2V | 13.6V | 11.5V | 11.0V |
| 1 | 密封电池 | 14.4V | 13.6V | 11.5V | 11.0V |
| 2 | 磷酸铁锂 | 14.4V | 14.4V | 11.5V | 11.0V |
| 3 | 三元锂电 | 12.6V | 12.6V | 9.5V | 9.0V |
| 4 | 自定义 | - | - | - | - |
| 5 | 加水电池 | 14.6V | 13.6V | 11.5V | 11.0V |
| 代码 | 故障描述 | 严重程度 |
|---|---|---|
| 20 | 正常 | - |
| 30 | 光伏板超压 | 高 |
| 31 | 光伏充电过流 | 高 |
| 32 | 电池电压低 | 中 |
| 33 | 电池超压 | 高 |
| 38 | 设备温度高 | 中 |
| 50 | 温度传感器故障 | 中 |
| 88 | 未解密 | 低 |
| 值 | 电压等级 | 说明 |
|---|---|---|
| 0 | 自动识别 | 自动检测电池电压 |
| 1 | 12V | |
| 2 | 24V | |
| 3 | 36V | |
| 4 | 48V | |
| 5 | 60V | |
| 6 | 72V |
最后更新: 2026-08-05 (v2.0.0)