首次运行
本节指导你启动 EnerOS API 服务器,验证服务可用性,并执行第一次潮流计算。同时介绍 Dashboard、日志、健康检查以及停止与重启等运行管理操作。
启动 API 服务器
构建完成后,可通过 eneros-api 二进制启动 API 服务器。
启动选项
# 使用默认配置启动
./target/release/eneros-api
# 指定配置文件
./target/release/eneros-api --config eneros.toml
# 指定监听地址与端口
./target/release/eneros-api --host 0.0.0.0 --port 9090
# 启用 Dashboard
./target/release/eneros-api --with-dashboard
# 指定日志级别
./target/release/eneros-api --log-level debug
# 后台运行(Linux / macOS)
nohup ./target/release/eneros-api > eneros.log 2>&1 &
# 查看进程
ps aux | grep eneros-api
命令行参数完整说明
| 参数 | 缩写 | 默认值 | 说明 |
|---|---|---|---|
--config | -c | eneros.toml | 配置文件路径 |
--host | -H | 0.0.0.0 | 监听地址 |
--port | -p | 8080 | 监听端口 |
--log-level | -l | info | 日志级别(trace/debug/info/warn/error) |
--with-dashboard | - | false | 启用 Web Dashboard |
--data-dir | -d | ./data | 数据目录 |
--pid-file | - | 无 | PID 文件路径 |
--daemon | - | false | 以守护进程方式运行 |
--version | -V | - | 打印版本号并退出 |
--help | -h | - | 打印帮助信息 |
启动后,API 服务器默认监听 http://localhost:8080。
配置文件加载顺序
EnerOS 按以下顺序查找配置文件,先找到的优先:
- 命令行
--config显式指定 - 当前目录的
eneros.toml ~/.eneros/eneros.toml(用户级)/etc/eneros/eneros.toml(系统级)- 内置默认值
如未找到任何配置文件,将使用内置默认配置并在日志中打印警告。
日志级别
EnerOS 使用 tracing 库输出结构化日志。可通过 --log-level 或环境变量控制:
# 命令行参数
./target/release/eneros-api --log-level debug
# 环境变量
export ENEROS_LOG=debug
./target/release/eneros-api
| 级别 | 用途 |
|---|---|
trace | 极详细,包含所有内部状态变化 |
debug | 调试信息,包含请求/响应详情 |
info | 关键业务事件(默认) |
warn | 警告,系统可继续运行 |
error | 错误,需关注 |
off | 关闭日志 |
启动日志示例
2026-07-06T10:00:00.123Z INFO eneros_api::server | EnerOS API Server v0.47.0
2026-07-06T10:00:00.124Z INFO eneros_api::server | Loading config from eneros.toml
2026-07-06T10:00:00.130Z INFO eneros_api::server | Listening on 0.0.0.0:8080
2026-07-06T10:00:00.131Z INFO eneros_api::server | Workers: 4
2026-07-06T10:00:00.132Z INFO eneros_topology::store | Topology cache initialized
2026-07-06T10:00:00.133Z INFO eneros_powerflow::solver | PowerFlow solver ready (newton-raphson)
2026-07-06T10:00:00.134Z INFO eneros_api::server | Dashboard enabled at /dashboard
2026-07-06T10:00:00.135Z INFO eneros_api::server | Ready to accept connections
验证服务
健康检查
curl http://localhost:8080/api/v1/health
预期响应:
{
"status": "ok",
"version": "0.47.0",
"uptime_seconds": 42,
"components": {
"database": "ok",
"topology": "ok",
"powerflow": "ok",
"agent_runtime": "ok",
"timeseries": "ok"
}
}
健康检查响应字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
status | string | 整体状态,ok / degraded / down |
version | string | EnerOS 版本号 |
uptime_seconds | number | 服务运行时长(秒) |
components | object | 各组件健康状态 |
components.database | string | 数据库状态 |
components.topology | string | 拓扑服务状态 |
components.powerflow | string | 潮流计算服务状态 |
components.agent_runtime | string | Agent 运行时状态 |
components.timeseries | string | 时序存储状态 |
就绪检查
# 区别于健康检查:就绪检查会等待依赖初始化完成
curl http://localhost:8080/api/v1/ready
# {"ready": true}
指标端点
# Prometheus 格式指标
curl http://localhost:8080/api/v1/metrics
执行潮流计算
通过 REST API(cURL)
步骤 1:创建电网网络
# 创建 IEEE 14-bus 测试网络
curl -X POST http://localhost:8080/api/v1/networks \
-H "Content-Type: application/json" \
-d '{
"name": "IEEE-14",
"source": "ieee14",
"description": "IEEE 14-bus standard test system"
}'
响应:
{
"network_id": "net_a1b2c3d4",
"name": "IEEE-14",
"bus_count": 14,
"branch_count": 20,
"generator_count": 5,
"created_at": "2026-07-06T10:00:00Z"
}
步骤 2:执行潮流计算
# 执行牛顿-拉夫逊法潮流计算
curl -X POST http://localhost:8080/api/v1/networks/net_a1b2c3d4/powerflow \
-H "Content-Type: application/json" \
-d '{
"method": "newton-raphson",
"tolerance": 1e-8,
"max_iterations": 20,
"flat_start": false
}'
响应:
{
"result_id": "pf_x1y2z3",
"network_id": "net_a1b2c3d4",
"method": "newton-raphson",
"converged": true,
"iterations": 4,
"duration_ms": 11.8,
"buses": [
{"id": 1, "voltage": 1.060, "angle": 0.00, "type": "slack"},
{"id": 2, "voltage": 1.045, "angle": -4.98, "type": "PV"},
{"id": 3, "voltage": 1.010, "angle": -12.72, "type": "PV"},
{"id": 4, "voltage": 1.019, "angle": -10.31, "type": "PQ"}
],
"branches": [
{"from": 1, "to": 2, "power_mw": 156.9, "loss_mw": 0.42}
],
"total_loss_mw": 13.79,
"timestamp": "2026-07-06T10:00:01Z"
}
潮流计算参数详解
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
method | string | newton-raphson | 求解方法(newton-raphson / fast-decoupled / dc / gauss-seidel) |
tolerance | number | 1e-8 | 收敛精度(标幺值) |
max_iterations | number | 20 | 最大迭代次数 |
flat_start | boolean | false | 是否平启动(电压初值全 1.0) |
q_limit_check | boolean | true | 是否进行无功越限检查 |
tap_adjust | boolean | true | 是否调整变压器变比 |
通过 Rust 代码
use eneros_powerflow::PowerFlowSolver;
use eneros_topology::NetworkGraph;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 加载 IEEE 14-bus 网络
let network = NetworkGraph::load_ieee14()?;
// 创建潮流求解器
let solver = PowerFlowSolver::new()
.method(eneros_powerflow::Method::NewtonRaphson)
.tolerance(1e-8)
.max_iterations(20)
.flat_start(false);
// 执行潮流计算
let result = solver.solve(&network)?;
// 输出结果
println!("Converged: {}", result.converged);
println!("Iterations: {}", result.iterations);
println!("Duration: {:.2} ms", result.duration_ms);
for bus in &result.buses {
println!(
"Bus {:>3}: V={:.4} pu, angle={:.2}°, P={:.2} MW, Q={:.2} MVAr",
bus.id,
bus.voltage,
bus.angle.to_degrees(),
bus.power_mw,
bus.reactive_mvar
);
}
println!("Total loss: {:.4} MW", result.total_loss_mw);
Ok(())
}
将上述代码加入 examples/powerflow_demo.rs,然后运行:
cargo run --release --example powerflow_demo
预期输出:
Converged: true
Iterations: 4
Duration: 11.80 ms
Bus 1: V=1.0600 pu, angle=0.00°, P=0.00 MW, Q=0.00 MVAr
Bus 2: V=1.0450 pu, angle=-4.98°, P=18.30 MW, Q=0.00 MVAr
Bus 3: V=1.0100 pu, angle=-12.72°, P=-94.20 MW, Q=0.00 MVAr
Bus 4: V=1.0186 pu, angle=-10.31°, P=-47.80 MW, Q=-3.90 MVAr
...
Total loss: 13.7934 MW
通过 Python 客户端
import requests
BASE_URL = "http://localhost:8080/api/v1"
# 创建网络
resp = requests.post(
f"{BASE_URL}/networks",
json={
"name": "IEEE-14",
"source": "ieee14",
"description": "IEEE 14-bus standard test system"
}
)
network = resp.json()
network_id = network["network_id"]
print(f"Network created: {network_id}")
# 执行潮流计算
resp = requests.post(
f"{BASE_URL}/networks/{network_id}/powerflow",
json={
"method": "newton-raphson",
"tolerance": 1e-8,
"max_iterations": 20,
"flat_start": False
}
)
result = resp.json()
print(f"Converged: {result['converged']}")
print(f"Iterations: {result['iterations']}")
print(f"Duration: {result['duration_ms']} ms")
print(f"Total loss: {result['total_loss_mw']} MW")
for bus in result["buses"]:
print(f"Bus {bus['id']:>3}: V={bus['voltage']:.4f} pu, "
f"angle={bus['angle']:.2f}°")
运行:
python powerflow_demo.py
访问 Dashboard
如果使用 --with-dashboard 启动,访问 http://localhost:8080/dashboard 即可使用内置 Web Dashboard。
Dashboard 功能
| 功能模块 | 路径 | 说明 |
|---|---|---|
| 概览 | /dashboard | 系统总览,关键指标 |
| 拓扑可视化 | /dashboard/topology | 电网拓扑图形化展示 |
| 潮流结果 | /dashboard/powerflow | 潮流计算结果可视化 |
| Agent 监控 | /dashboard/agents | Agent 运行状态与日志 |
| 时序数据 | /dashboard/timeseries | 时序数据图表 |
| 告警 | /dashboard/alerts | 实时告警列表 |
| 设置 | /dashboard/settings | 系统设置 |
Dashboard 操作示例
- 查看拓扑:访问
/dashboard/topology,可拖拽节点布局,点击节点查看设备详情 - 触发潮流:在拓扑页点击 “Run PowerFlow” 按钮
- 查看 Agent:访问
/dashboard/agents,查看运行中 Agent 列表 - 查看实时曲线:访问
/dashboard/timeseries,选择测点绘制曲线
错误处理
常见错误响应
EnerOS API 使用统一的错误响应格式:
{
"error": {
"code": "POWERFLOW_NOT_CONVERGED",
"message": "Power flow calculation did not converge within 20 iterations",
"details": {
"iterations": 20,
"final_mismatch": 0.0123,
"network_id": "net_a1b2c3d4"
}
}
}
错误码表
| HTTP | code | 说明 |
|---|---|---|
| 400 | INVALID_REQUEST | 请求参数错误 |
| 401 | UNAUTHORIZED | 未认证 |
| 403 | FORBIDDEN | 无权限 |
| 404 | NETWORK_NOT_FOUND | 网络不存在 |
| 404 | BUS_NOT_FOUND | 母线不存在 |
| 409 | NETWORK_EXISTS | 网络已存在 |
| 422 | POWERFLOW_NOT_CONVERGED | 潮流不收敛 |
| 422 | CONSTRAINT_VIOLATION | 违反安全约束 |
| 500 | INTERNAL_ERROR | 内部错误 |
| 503 | SERVICE_UNAVAILABLE | 服务不可用 |
处理潮流不收敛
# 当返回 POWERFLOW_NOT_CONVERGED 时,尝试以下方法:
# 1. 增大迭代次数
curl -X POST http://localhost:8080/api/v1/networks/net_a1b2c3d4/powerflow \
-H "Content-Type: application/json" \
-d '{"method":"newton-raphson","max_iterations":50,"tolerance":1e-6}'
# 2. 使用平启动
curl -X POST http://localhost:8080/api/v1/networks/net_a1b2c3d4/powerflow \
-H "Content-Type: application/json" \
-d '{"method":"newton-raphson","flat_start":true,"max_iterations":50}'
# 3. 改用快速解耦法
curl -X POST http://localhost:8080/api/v1/networks/net_a1b2c3d4/powerflow \
-H "Content-Type: application/json" \
-d '{"method":"fast-decoupled","max_iterations":50}'
# 4. 直流潮流(近似解)
curl -X POST http://localhost:8080/api/v1/networks/net_a1b2c3d4/powerflow \
-H "Content-Type: application/json" \
-d '{"method":"dc"}'
停止与重启
优雅停止
# 发送 SIGTERM
kill $(cat eneros.pid)
# 或使用 enerosctl
./target/release/enerosctl server stop
# 等待 30 秒未退出后强制结束
kill -9 $(cat eneros.pid)
重启
# 使用 enerosctl
./target/release/enerosctl server restart
# 手动重启
./target/release/enerosctl server stop
./target/release/eneros-api --config eneros.toml
systemd 服务(Linux)
# /etc/systemd/system/eneros.service
[Unit]
Description=EnerOS API Server
After=network.target
[Service]
Type=simple
User=eneros
ExecStart=/opt/eneros/bin/eneros-api --config /etc/eneros/eneros.toml
ExecStop=/opt/eneros/bin/enerosctl server stop
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable eneros
sudo systemctl start eneros
sudo systemctl status eneros
常见运行问题
问题 1:端口被占用
Error: Address already in use (os error 98)
解决:
# 查看占用进程
lsof -i :8080 # Linux / macOS
netstat -ano | findstr :8080 # Windows
# 终止占用进程
kill -9 <PID>
# 或更换端口启动
./target/release/eneros-api --port 9090
问题 2:数据库文件锁定
Error: database is locked
解决:已有进程占用数据库。检查是否有另一个 eneros-api 实例:
ps aux | grep eneros-api
问题 3:权限不足
Error: Permission denied (os error 13)
解决:
# 检查数据目录权限
ls -la ./data/
# 修改所有者
sudo chown -R $USER:$USER ./data/
问题 4:潮流结果为空
原因:网络 ID 错误,或网络未加载。
解决:
# 列出所有网络
curl http://localhost:8080/api/v1/networks
# 确认 network_id 后重试
下一步
- 首个 Agent - 创建并运行你的第一个 EnerOS Agent