0e28826073
- 升级 Drogon 和 Trantor,修复畸形请求导致的连接计数泄漏\n- 增加第三方框架版本校验与自动重建\n- 完善完整报告导出和接口文档
281 lines
6.7 KiB
Markdown
281 lines
6.7 KiB
Markdown
# 接口文档
|
||
|
||
## 通用响应
|
||
|
||
后端接口统一返回:
|
||
|
||
```json
|
||
{
|
||
"status": 0,
|
||
"msg": "success",
|
||
"data": {}
|
||
}
|
||
```
|
||
|
||
`status` 为 `0` 表示成功,非 `0` 表示业务失败。
|
||
|
||
## 系统接口
|
||
|
||
### GET /api/system/health
|
||
|
||
返回服务健康状态。
|
||
|
||
成功响应:
|
||
|
||
```json
|
||
{
|
||
"status": 0,
|
||
"msg": "success",
|
||
"data": {
|
||
"status": "ok"
|
||
}
|
||
}
|
||
```
|
||
|
||
### GET /api/system/version
|
||
|
||
返回服务版本信息。
|
||
|
||
成功响应:
|
||
|
||
```json
|
||
{
|
||
"status": 0,
|
||
"msg": "success",
|
||
"data": {
|
||
"name": "wind_power_cal",
|
||
"version": "0.1.0"
|
||
}
|
||
}
|
||
```
|
||
|
||
## 风功率计算接口
|
||
|
||
### POST /api/wind/jobs/start
|
||
|
||
创建风功率计算任务。服务器全局同一时刻仅允许一个上传、计算或报告生成任务;繁忙时返回 `status: 1004` 和“服务器正在处理数据,请等待当前任务完成”。
|
||
|
||
请求:
|
||
|
||
```json
|
||
{
|
||
"files": [
|
||
{
|
||
"file_name": "01_风机历史数据.xls",
|
||
"row_count": 51906
|
||
}
|
||
],
|
||
"mapping": {
|
||
"time": "时间",
|
||
"fan_id": "风机编号",
|
||
"wind_speed": "风速(m/s)",
|
||
"active_power": "有功功率(kW)",
|
||
"generator_speed": "发电机转速(rpm)"
|
||
},
|
||
"raw_headers": ["时间", "风机编号", "风速(m/s)", "有功功率(kW)", "发电机转速(rpm)"]
|
||
}
|
||
```
|
||
|
||
成功响应:
|
||
|
||
```json
|
||
{
|
||
"status": 0,
|
||
"msg": "success",
|
||
"data": {
|
||
"job_id": "job_123"
|
||
}
|
||
}
|
||
```
|
||
|
||
### POST /api/wind/jobs/chunk
|
||
|
||
上传标准化后的数据分片。`raw_rows` 保存原始 Excel 行,用于服务端完整报告的“筛选前的数据”工作表。
|
||
|
||
请求:
|
||
|
||
```json
|
||
{
|
||
"job_id": "job_123",
|
||
"chunk_index": 0,
|
||
"rows": [
|
||
{
|
||
"time": "2024-09-01 14:00:00",
|
||
"fan_id": "01#",
|
||
"wind_speed": 3.414,
|
||
"active_power": 114.3471,
|
||
"generator_speed": 1109.3143
|
||
}
|
||
],
|
||
"raw_rows": [
|
||
{"file_name": "01_风机历史数据.xls", "values": ["2024-09-01 14:00:00", "01#", 3.414, 114.3471, 1109.3143]}
|
||
]
|
||
}
|
||
```
|
||
|
||
成功响应:
|
||
|
||
```json
|
||
{
|
||
"status": 0,
|
||
"msg": "success",
|
||
"data": {
|
||
"accepted_rows": 1
|
||
}
|
||
}
|
||
```
|
||
|
||
### POST /api/wind/jobs/finish
|
||
|
||
完成任务并执行清洗、排序、分箱和功率曲线计算。
|
||
|
||
请求:
|
||
|
||
```json
|
||
{
|
||
"job_id": "job_123",
|
||
"options": {
|
||
"rated_power": 4800,
|
||
"rated_wind_speed": 14,
|
||
"power_step": 5,
|
||
"cleaning_wind_speed_step": 0.25,
|
||
"curve_wind_speed_step": 0.5,
|
||
"wind_speed_change_threshold": 1,
|
||
"iqr_lower_multiplier": 1.2,
|
||
"iqr_upper_multiplier": 2,
|
||
"minimum_generator_speed": 1,
|
||
"generator_speed_k": 0.9,
|
||
"rotor_radius": 78,
|
||
"gearbox_ratio": 162,
|
||
"report_wind_speed_interval": 0.25
|
||
}
|
||
}
|
||
```
|
||
|
||
成功响应:
|
||
|
||
```json
|
||
{
|
||
"status": 0,
|
||
"msg": "success",
|
||
"data": {
|
||
"summary": {
|
||
"raw_rows": 51906,
|
||
"valid_rows": 38017,
|
||
"invalid_rows": 13889,
|
||
"duplicate_rows": 0,
|
||
"limit_power_rows": 0,
|
||
"tip_speed_ratio_outlier_rows": 0,
|
||
"speed_power_outlier_rows": 0,
|
||
"high_wind_low_power_rows": 0,
|
||
"curve_residual_outlier_rows": 0,
|
||
"rated_plateau_low_power_rows": 0,
|
||
"invalid_reasons": {
|
||
"invalid_active_power": 13889,
|
||
"limit_power": 0,
|
||
"tip_speed_ratio_outlier": 0,
|
||
"speed_power_outlier": 0,
|
||
"high_wind_low_power": 0,
|
||
"curve_residual_outlier": 0,
|
||
"rated_plateau_low_power": 0
|
||
},
|
||
"fan_count": 1
|
||
},
|
||
"fans": ["01#"],
|
||
"curves": {
|
||
"01#": [
|
||
{
|
||
"wind_speed_start": 3.0,
|
||
"wind_speed_end": 3.5,
|
||
"wind_speed": 3.25,
|
||
"sample_count": 120,
|
||
"average_power": 180.5,
|
||
"median_power": 176.2,
|
||
"stddev_power": 32.1,
|
||
"p25_power": 150.0,
|
||
"p75_power": 205.0,
|
||
"confidence": "脚本分箱"
|
||
}
|
||
]
|
||
},
|
||
"bins": {
|
||
"01#": []
|
||
},
|
||
"scatter_points": {
|
||
"01#": [
|
||
{
|
||
"wind_speed": 3.414,
|
||
"active_power": 114.3471
|
||
}
|
||
]
|
||
},
|
||
"filtered_points": {
|
||
"01#": [
|
||
{
|
||
"wind_speed": 5.2,
|
||
"active_power": 430.0,
|
||
"reason": "speed_power_outlier"
|
||
}
|
||
]
|
||
},
|
||
"estimated_params": {
|
||
"01#": {
|
||
"rated_power": 3120.5,
|
||
"rated_wind_speed": 10.75,
|
||
"source": "auto"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
清洗规则:
|
||
|
||
- `active_power <= 0` 的数据剔除。
|
||
- `generator_speed < generator_speed_k * minimum_generator_speed` 的数据剔除。
|
||
- 时间不可解析的数据剔除。
|
||
- 风机编号为空的数据剔除。
|
||
- `wind_speed <= 0` 的数据剔除。
|
||
- 同一风机同一时间重复记录保留第一条。
|
||
- 限功率识别按参考脚本执行:按功率分箱、按日期分组,组内风速跨度大于阈值时剔除。
|
||
- 叶尖速比按 `generator_speed * 3.14 * gearbox_ratio * rotor_radius * 30 / wind_speed` 计算;`3.14` 和 `30` 固定,叶轮半径与齿轮箱传动比由方案一参数提供,再按风速分箱做 IQR 清洗。
|
||
- 风速-功率关系按同一风速分箱和 IQR 参数清洗。
|
||
- 每台风机在 IQR 清洗后自动估算平台功率和平台起始风速,返回到 `estimated_params`。
|
||
- 高风速平台区明显低于平台功率的点剔除为 `high_wind_low_power`。
|
||
- 基于分箱中位功率曲线的残差异常点剔除为 `curve_residual_outlier`。
|
||
- 严格额定平台区残留偏低点剔除为 `rated_plateau_low_power`。
|
||
- 最终曲线按 `curve_wind_speed_step` 左开右闭分箱,区间非空即输出平均功率点。
|
||
- `report_wind_speed_interval` 为完整报告 Sheet3 的公式区间半宽,默认 `0.25 m/s`,取值范围 `(0, 2]`;方案一、方案二分别保存。
|
||
- `scatter_points` 返回清洗后保留点,`filtered_points` 返回所有过滤阶段滤除的点和原因。
|
||
- `estimated_params.source` 为 `auto`、`auto_power_fallback_wind` 或 `fallback`。
|
||
|
||
### POST /api/wind/jobs/{jobId}/report
|
||
|
||
服务端以常量内存方式生成完整报告并直接返回 `.xlsx` 附件。计算完成的数据保留 24 小时;上传任务连续 30 分钟未活动会自动清理。
|
||
|
||
请求体包含 `fan_id`、当前编辑后的 `effective_rows`、`report_rows` 和可选的 `chart_image`(PNG data URL)。成功时响应为 Excel 文件流;失败时仍使用统一 JSON 响应信封。
|
||
|
||
### DELETE /api/wind/jobs/{job_id}
|
||
|
||
清理未完成任务的临时文件。
|
||
|
||
成功响应:
|
||
|
||
```json
|
||
{
|
||
"status": 0,
|
||
"msg": "success",
|
||
"data": null
|
||
}
|
||
```
|
||
|
||
### GET /api/wind/chart-options
|
||
|
||
读取全局图表样式配置。未保存时返回 `configured: false`;已保存时 `options.text_scale`
|
||
为文字倍率,取值范围 `0.75~1.50`,其中 `1.00` 为默认倍率。
|
||
|
||
### POST /api/wind/chart-options
|
||
|
||
保存全局图表样式配置。请求体包含当前图表全部样式字段,其中 `text_scale` 为必填数字,
|
||
取值范围 `0.75~1.50`。旧配置中的 `text_size` 会在读取时自动换算为倍率。
|