158-基于FLask的风电场风力发电数据分析可视化

风电场风力发电数据分析可视化系统 — 技术文档

版本: 1.0 | 更新日期: 2026-06-21


1. 项目概述

基于 Flask 的风电场数据分析可视化平台,对 2019 年全年 35,040 条(15 分钟间隔)风电场运行数据进行多维分析、异常检测、产能效率评估和功率预测。

技术栈: Flask + SQLAlchemy + SQLite + ECharts 5.4.3 + NumPy + Pandas

代码规模: 6 个 Python 源文件(约 1,670 行)、19 个 HTML 模板(约 2,300 行)、1 个 CSS 文件(792 行),总计约 4,855 行。


2. 系统架构

┌─────────────────────────────────────────────────────────┐ │ 浏览器 (ECharts) │ ├─────────────────────────────────────────────────────────┤ │ Flask 路由层 (app.py) │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ │ │ │ 认证路由 │ │ 页面路由 │ │ 分析API │ │ 管理API │ │ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬────┘ │ │ │ │ │ │ │ │ ┌────▼─────────────▼─────────────▼──────────────▼────┐ │ │ │ SQLAlchemy ORM + NumPy │ │ │ └────────────────────┬───────────────────────────────┘ │ │ │ │ │ ┌────────────────────▼───────────────────────────────┐ │ │ │ SQLite (wind_farm.db) │ │ │ │ users 表 + wind_data 表 (35,040 行) │ │ │ └────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘

数据流:

CSV (风电场_2019.csv) → init_db.py 批量导入 → SQLite → Flask API (SQL GROUP BY / NumPy 计算) → JSON → 前端 ECharts 渲染























3. 目录结构

cloud/ ├── app.py # 主应用:所有路由和 API 逻辑 (1418 行) ├── models.py # SQLAlchemy 数据模型 (76 行) ├── config.py # 应用配置 (9 行) ├── init_db.py # 数据库初始化 + CSV 导入 (72 行) ├── requirements.txt # Python 依赖 ├── wind_farm.db # SQLite 数据库 (11 MB) ├── 风电场_2019.csv # 原始数据 (35,040 行, 3.9 MB) ├── utils/ │ ├── __init__.py │ └── prediction.py # 预测工具函数 (97 行) ├── templates/ │ ├── base.html # 基础布局 (侧边栏、顶栏、加载动画) │ ├── login.html # 登录页 │ ├── register.html # 注册页 │ ├── index.html # 数据总览仪表盘 │ ├── profile.html # 个人中心 │ ├── analysis_wind_speed.html # 风速分析 │ ├── analysis_wind_direction.html # 风向分析 │ ├── analysis_power.html # 功率分析 │ ├── analysis_meteorological.html # 气象分析 │ ├── analysis_time_series.html # 时序分析 │ ├── analysis_correlation.html # 相关性分析 │ ├── analysis_advanced.html # 高级图表 (10 种) │ ├── prediction.html # 功率预测 │ ├── anomaly_detection.html # 异常检测 │ ├── comparison.html # 月度对比 │ ├── production_efficiency.html # 产能效率分析 │ ├── data_manage.html # 数据管理 (admin) │ └── user_manage.html # 用户管理 (admin) └── static/ ├── css/style.css # 暗色主题样式 (792 行) └── img/wind-farm-bg.jpg # 登录页背景图

4. 数据库设计

4.1 用户表users

字段类型约束说明
idINTEGERPK, 自增用户 ID
usernameVARCHAR(80)UNIQUE, NOT NULL用户名
password_hashVARCHAR(256)NOT NULLWerkzeug 加密后的密码
emailVARCHAR(120)邮箱
phoneVARCHAR(20)手机号
avatarVARCHAR(256)DEFAULT ‘’头像 (emoji)
roleVARCHAR(20)DEFAULT ‘user’角色: user / admin
created_atDATETIMEDEFAULT NOW注册时间

4.2 风电数据表wind_data

字段类型说明
idINTEGER (PK)记录 ID
timestampDATETIME (INDEXED)时间戳,15 分钟间隔
wind_speed_10mFLOAT10 米高度风速 (m/s)
wind_speed_30mFLOAT30 米高度风速 (m/s)
wind_speed_50mFLOAT50 米高度风速 (m/s)
wind_speed_70mFLOAT70 米高度风速 (m/s)
wind_speed_hubFLOAT轮毂高度风速 (m/s)
wind_dir_10mFLOAT10 米高度风向 (°)
wind_dir_30mFLOAT30 米高度风向 (°)
wind_dir_50mFLOAT50 米高度风向 (°)
wind_dir_70mFLOAT70 米高度风向 (°)
wind_dir_hubFLOAT轮毂高度风向 (°)
temperatureFLOAT温度 (°C)
pressureFLOAT气压 (hPa)
humidityFLOAT湿度 (%)
powerFLOAT实际发电功率 (MW)

4.3 数据库索引

CREATEINDEXidx_wind_timestampONwind_data(timestamp);CREATEINDEXidx_wind_power_tsONwind_data(timestamp,power);CREATEINDEXidx_wind_speed_tsONwind_data(timestamp,wind_speed_hub);
  • idx_wind_timestamp: 支持所有时间范围查询和 ORDER BY
  • idx_wind_power_ts: 覆盖索引,功率查询无需回表
  • idx_wind_speed_ts: 覆盖索引,风速查询无需回表

5. API 接口文档

5.1 统一响应格式

// 成功{"code":0,"data":{...}}// 错误{"code":1,"msg":"错误信息"}// 分页{"code":0,"data":[...],"total":35040,"page":1,"limit":20}

5.2 认证接口

方法路径说明
GET/POST/login登录,支持 JSON 和表单
GET/POST/register注册,首个用户自动成为 admin
GET/logout退出登录
GET/POST/profile个人信息编辑(头像、邮箱、手机号、密码)

认证方式:Session-based,使用werkzeug.securitygenerate_password_hash/check_password_hash

5.3 仪表盘

方法路径说明
GET/api/dashboard/summary总览统计

返回字段:total_records,date_range,avg_power,max_power,total_energy,avg_speed,avg_temp

5.4 分析接口

所有分析接口支持?month=YYYY-MM参数筛选月份。

/api/analysis/wind_speed— 风速分析
{"monthly_avg":{"1":{"hub":5.32,"10m":4.10,"30m":4.85,"50m":5.12,"70m":5.45}},"frequency":{"labels":["0-1","1-2",...],"values":[2.1,5.3,...]},"time_series":{"timestamps":[...],"hub":[...],"10m":[...],"70m":[...]},"stats":{"hub_avg":6.28,"hub_max":18.5,"hub_min":0.0,"hub_std":3.41}}
/api/analysis/wind_direction— 风向分析
{"rose":{"labels":["N","NNE",...],"frequency":{"N":8.5,...},"avg_speed":{"N":5.2,...}},"monthly_rose":{"1":{"N":12.3,...},"2":{...}},"heights":{"10m":{"N":10.2,...},"hub":{"N":8.5,...}}}
/api/analysis/power— 功率分析
{"curve":{"labels":["0-1","1-2",...],"values":[0.0,0.5,...]},"monthly_avg":{"1":45.2,"2":52.1,...},"monthly_sum":{"1":33450.0,...},"distribution":{"labels":["0.0-10.0",...],"values":[1200,...]},"time_series":{"timestamps":[...],"power":[...],"wind_speed":[...]},"daily_energy":{"dates":["2019-01-01",...],"values":[2850.5,...]},"stats":{"avg_power":48.5,"max_power":198.2,"total_energy":425000.0,"capacity_factor":24.3}}
/api/analysis/meteorological— 气象分析

返回月度均值、散点数据(温度-功率、湿度-功率、气压-功率)、时间序列、统计值。

/api/analysis/time_series— 时序分析

支持?agg=hour|day|week|month参数,返回聚合后的时间序列和自相关系数(滞后 1-48)。

/api/analysis/correlation— 相关性分析

返回 10×10 相关系数矩阵和两组散点数据(轮毂风速-功率、温度-功率)。

/api/analysis/advanced— 高级图表

一次返回 10 种图表数据:漏斗图、桑基图、河流图(堆叠柱状图)、箱线图、气泡图、季节小时模式、月度风玫瑰、累计发电量曲线、热力图、风速持续曲线。

/api/prediction— 功率预测
{"power_curve":{"speeds":[0,1,...,25],"powers":[0.0,0.5,...]},"monthly":{"1":{"avg_speed":5.32,"avg_power":45.2,"total_power":33450.0}},"daily_forecast":{"historical_dates":[...],"historical_values":[...],"forecast_values":[...]},"hourly_pattern":{"0":32.1,"1":28.5,...,"23":35.2},"weibull":{"labels":["0-1","1-2",...],"values":[2.1,5.3,...]}}

5.5 数据洞察接口

/api/data/quality— 产能效率分析

基于贝茨极限(Betz Limit, Cp=16/27)计算理论最大发电量,与实际发电量对比:

  • 转换效率 = 实际功率 / 理论功率 × 100%
  • 容量因子 = 实际发电量 / (额定功率 × 运行小时数) × 100%
  • 损失电量 = 理论发电量 - 实际发电量

物理参数:空气密度 ρ=1.225 kg/m³,叶轮半径 R=40m,额定功率 200MW。

/api/anomaly/detection— 异常检测

使用 IQR(四分位距)方法:

Q1, Q3 = np.percentile(values, [25, 75]) IQR = Q3 - Q1 异常范围: < Q1 - 1.5×IQR 或 > Q3 + 1.5×IQR

分别检测风速、功率、温度三个维度的异常值,返回时间线和分布数据。

/api/comparison— 月度对比

返回月度发电量、风速、功率对比数据及环比变化率,标识最佳/最差月份。

5.6 管理接口

方法路径说明权限
GET/api/data/list?page=1&limit=20&month=2019-03分页数据列表admin
POST/api/data/delete/<id>删除记录admin
POST/api/data/update/<id>更新记录admin
GET/api/user/list用户列表admin
POST/api/user/add添加用户admin
POST/api/user/update/<id>更新用户admin
POST/api/user/delete/<id>删除用户admin
GET/api/export/csv?month=2019-03CSV 导出login

6. 核心算法

6.1 功率曲线预测

使用 3 次多项式拟合风速-功率关系:

coeffs=np.polyfit(wind_speeds,powers,3)poly=np.poly1d(coeffs)predicted=poly(predict_speeds)predicted[predicted<0]=0# 负值截断

6.2 风速频率分布(类 Weibull)

bins=np.arange(0,max_speed+bin_size,bin_size)hist,edges=np.histogram(wind_speeds,bins=bins)frequency=hist/len(wind_speeds)*100# 百分比

6.3 功率曲线(分箱均值)

bin_indices=np.digitize(wind_speeds,bins)foriinrange(len(bins)):mask=bin_indices==i curve[i]=np.mean(powers[mask])ifmask.any()else0

6.4 加权移动平均预测

val=0.5*recent[-1]+0.3*recent[-2]+0.2*recent[-3]

基于最近 14 天数据,滑动窗口向前预测 7 天。

6.5 IQR 异常检测

q1,q3=np.percentile(values,[25,75])iqr=q3-q1 outliers=(values<q1-1.5*iqr)|(values>q3+1.5*iqr)

6.6 自相关分析

forlaginrange(1,49):corr=np.corrcoef(speeds[:-lag],speeds[lag:])[0,1]

用于检测风速的时间周期性。

6.7 产能效率(贝茨极限)

P_theoretical=0.5× ρ × A × v³ × Cp/10# MW# ρ = 1.225 kg/m³, A = π × 40² m², Cp = 16/27efficiency=P_actual/P_theoretical ×100%capacity_factor=E_actual/(P_rated × hours)×100%

7. 前端设计

7.1 配色方案

深色数据分析主题,主色调为琥珀金:

变量色值用途
--bg-primary#0c0f14页面背景
--bg-card#1a1f2b卡片背景
--accent-primary#f59e0b主色调(琥珀金)
--accent-green#10b981正向数据
--accent-red#ef4444负向/异常
--accent-teal#14b8a6辅助色
--text-primary#e8eaed主文本
--text-secondary#9aa0ad次文本

7.2 图表技术

  • ECharts 5.4.3(CDN 引入)
  • 图表类型:折线图、柱状图、面积图、雷达图、玫瑰图、散点图、箱线图、桑基图、漏斗图、河流图、热力图、持续曲线
  • 所有图表支持响应式 resize
  • 加载时显示骨架屏 shimmer 动画

7.3 布局结构

┌──────────┬──────────────────────────────┐ │ │ 页面标题栏 │ │ 侧边栏 ├──────────────────────────────┤ │ (240px) │ │ │ │ 页面内容区 │ │ 导航菜单 │ (卡片网格 / 图表容器) │ │ │ │ │ │ │ │ 用户信息 ├──────────────────────────────┤ └──────────┴──────────────────────────────┘

响应式断点:768px 以下侧边栏隐藏,图表网格变为单列。


8. 用户角色与权限

功能普通用户 (user)管理员 (admin)
查看仪表盘
所有分析页面
功率预测
个人中心
数据管理(CRUD)
用户管理(CRUD)
CSV 导出

首个注册用户自动成为管理员(migrate_db()中实现)。


9. 数据处理流程

9.1 数据导入

风电场_2019.csv (UTF-8-BOM) ↓ pandas read_csv(encoding='utf-8-sig') ↓ 列名映射(中文→英文) ↓ 时间戳解析 ('%Y/%m/%d %H:%M') ↓ bulk_save_objects (1000条/批) ↓ wind_farm.db (35,040 行)

9.2 查询优化策略

场景策略示例
月度/日度/小时聚合SQL GROUP BYstrftime('%m', timestamp)+.group_by()
时间范围筛选半开区间[start, end)_month_filter()辅助函数
大数据量展示尾部截取 500 点records[-500:]
散点图数据等步长采样data[::max(1, len(data)//500)]
缺失值标记哨兵值过滤> -50阈值,SQL 和 Python 双层过滤

9.3 能量计算

INTERVAL_HOURS=0.25# 15 分钟间隔energy_MWh=sum(power)×0.25

10. 部署与运行

10.1 环境要求

  • Python 3.11+
  • 依赖:Flask 3.0.0, Flask-SQLAlchemy 3.1.1, Werkzeug 3.0.1, pandas 2.1.4, numpy 1.26.2

10.2 启动步骤

# 1. 安装依赖pipinstall-rrequirements.txt# 2. 初始化数据库(首次运行)python init_db.py# 3. 启动应用python app.py# 访问 http://127.0.0.1:5001

10.3 数据库迁移

app.py中的migrate_db()在启动时自动执行:

  • 检查users表是否有role列,无则添加
  • 创建wind_data表的三个索引
  • 首个用户自动设为 admin

11. 已知限制

  1. SQLite 单写锁:并发写入时会排队,适合单用户或低并发场景
  2. scikit-learn 未使用requirements.txt中列出但代码未引用,可移除
  3. User.to_dict() 重复定义models.py中有两个同名方法,第二个覆盖第一个
  4. predict_monthly_power() 未使用utils/prediction.py中定义但从未调用
  5. 硬编码物理参数:贝茨极限计算中的叶轮半径(40m)和额定功率(200MW)为假设值
  6. 单年数据:仅包含 2019 年数据,无法做跨年同比分析