Compare commits
4 Commits
67b1f55b92
...
c54ad369a4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c54ad369a4 | ||
|
|
86e0e21b58 | ||
|
|
60a9a57cee | ||
|
|
db6114ef57 |
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Python-generated files
|
||||||
|
__pycache__/
|
||||||
|
*.py[oc]
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
wheels/
|
||||||
|
*.egg-info
|
||||||
|
|
||||||
|
# Virtual environments
|
||||||
|
.venv
|
||||||
|
|
||||||
|
# Build artifacts
|
||||||
|
version_info.txt
|
||||||
|
version.py
|
||||||
1
.python-version
Normal file
1
.python-version
Normal file
@@ -0,0 +1 @@
|
|||||||
|
cpython-3.12.12-windows-x86_64-none
|
||||||
BIN
Z4(22MW)-4-9行-需重新布置集电海缆-换流站在西侧.xls
Normal file
BIN
Z4(22MW)-4-9行-需重新布置集电海缆-换流站在西侧.xls
Normal file
Binary file not shown.
@@ -53,7 +53,8 @@ def create_template(output_file='windfarm_template.xlsx'):
|
|||||||
# Create System Parameters data
|
# Create System Parameters data
|
||||||
param_data = [
|
param_data = [
|
||||||
{'Parameter': 'Voltage (kV) / 电压 (kV)', 'Value': 66},
|
{'Parameter': 'Voltage (kV) / 电压 (kV)', 'Value': 66},
|
||||||
{'Parameter': 'Power Factor / 功率因数', 'Value': 0.95}
|
{'Parameter': 'Power Factor / 功率因数', 'Value': 0.95},
|
||||||
|
{'Parameter': 'Electricity Price (元/kWh) / 电价 (元/kWh)', 'Value': 0.4}
|
||||||
]
|
]
|
||||||
df_params = pd.DataFrame(param_data)
|
df_params = pd.DataFrame(param_data)
|
||||||
|
|
||||||
|
|||||||
118
gui.py
118
gui.py
@@ -128,6 +128,21 @@ def index():
|
|||||||
pf_str += " (默认)"
|
pf_str += " (默认)"
|
||||||
params_text.append(pf_str)
|
params_text.append(pf_str)
|
||||||
|
|
||||||
|
# 获取电价
|
||||||
|
ep = 0.4 # Default
|
||||||
|
is_default_ep = True
|
||||||
|
if (
|
||||||
|
state.get("system_params")
|
||||||
|
and "electricity_price" in state["system_params"]
|
||||||
|
):
|
||||||
|
ep = state["system_params"]["electricity_price"]
|
||||||
|
is_default_ep = False
|
||||||
|
|
||||||
|
ep_str = f"电价: {ep} 元/kWh"
|
||||||
|
if is_default_ep:
|
||||||
|
ep_str += " (默认)"
|
||||||
|
params_text.append(ep_str)
|
||||||
|
|
||||||
for p in params_text:
|
for p in params_text:
|
||||||
ui.chip(p, icon="bolt").props("outline color=primary")
|
ui.chip(p, icon="bolt").props("outline color=primary")
|
||||||
|
|
||||||
@@ -164,6 +179,12 @@ def index():
|
|||||||
"field": "cost",
|
"field": "cost",
|
||||||
"align": "center",
|
"align": "center",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "is_optional",
|
||||||
|
"label": "是否为可选",
|
||||||
|
"field": "is_optional",
|
||||||
|
"align": "center",
|
||||||
|
},
|
||||||
]
|
]
|
||||||
rows = []
|
rows = []
|
||||||
for spec in state["cable_specs"]:
|
for spec in state["cable_specs"]:
|
||||||
@@ -174,6 +195,7 @@ def index():
|
|||||||
"capacity": spec[1],
|
"capacity": spec[1],
|
||||||
"resistance": spec[2],
|
"resistance": spec[2],
|
||||||
"cost": spec[3],
|
"cost": spec[3],
|
||||||
|
"is_optional": "Y" if len(spec) > 4 and spec[4] else "",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
ui.table(columns=columns, rows=rows).classes("w-full").props(
|
ui.table(columns=columns, rows=rows).classes("w-full").props(
|
||||||
@@ -791,10 +813,14 @@ def index():
|
|||||||
elif "No Max" in original_name:
|
elif "No Max" in original_name:
|
||||||
note += "不包含可选电缆型号,且可使用的最大截面电缆降一档截面。"
|
note += "不包含可选电缆型号,且可使用的最大截面电缆降一档截面。"
|
||||||
|
|
||||||
|
# 计算总长度
|
||||||
|
total_length = sum(d["length"] for d in res["eval"]["details"])
|
||||||
|
|
||||||
row_dict = {
|
row_dict = {
|
||||||
"name": name_display,
|
"name": name_display,
|
||||||
"cost_wan": f"{res['cost'] / 10000:.2f}",
|
"cost_wan": f"{res['cost'] / 10000:.2f}",
|
||||||
"loss_kw": f"{res['loss']:.2f}",
|
"loss_kw": f"{res['loss']:.2f}",
|
||||||
|
"total_length": f"{total_length:.2f}",
|
||||||
"note": note,
|
"note": note,
|
||||||
"original_name": res["name"],
|
"original_name": res["name"],
|
||||||
}
|
}
|
||||||
@@ -914,50 +940,56 @@ def index():
|
|||||||
.style("max-height: 400px; overflow-y: auto;")
|
.style("max-height: 400px; overflow-y: auto;")
|
||||||
):
|
):
|
||||||
refs["info_container"] = ui.column().classes("w-full")
|
refs["info_container"] = ui.column().classes("w-full")
|
||||||
ui.label("请上传 Excel 文件以查看系统参数和电缆规格...").classes(
|
with refs["info_container"]:
|
||||||
"text-gray-500 italic"
|
ui.label("请上传 Excel 文件以查看系统参数和电缆规格...").classes(
|
||||||
)
|
"text-gray-500 italic"
|
||||||
|
)
|
||||||
|
|
||||||
with ui.card().classes("w-full p-4 shadow-md"):
|
with ui.card().classes("w-full p-0 shadow-md overflow-hidden"):
|
||||||
ui.label("方案对比结果 (点击行查看拓扑详情)").classes(
|
with ui.expansion(
|
||||||
"text-xl font-semibold mb-2"
|
"方案对比结果 (点击行查看拓扑详情)", icon="analytics", value=True
|
||||||
)
|
).classes("w-full").props("header-class=\"text-xl font-semibold\""):
|
||||||
columns = [
|
columns = [
|
||||||
{
|
{
|
||||||
"name": "name",
|
"name": "name",
|
||||||
"label": "方案名称",
|
"label": "方案名称",
|
||||||
"field": "name",
|
"field": "name",
|
||||||
"required": True,
|
"required": True,
|
||||||
"align": "left",
|
"align": "left",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "cost_wan",
|
"name": "cost_wan",
|
||||||
"label": "总投资 (万元)",
|
"label": "总投资 (万元)",
|
||||||
"field": "cost_wan",
|
"field": "cost_wan",
|
||||||
"sortable": True,
|
"sortable": True,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "loss_kw",
|
"name": "loss_kw",
|
||||||
"label": "线损 (kW)",
|
"label": "线损 (kW)",
|
||||||
"field": "loss_kw",
|
"field": "loss_kw",
|
||||||
"sortable": True,
|
"sortable": True,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "note",
|
"name": "total_length",
|
||||||
"label": "备注",
|
"label": "总长度 (m)",
|
||||||
"field": "note",
|
"field": "total_length",
|
||||||
"align": "left",
|
"sortable": True,
|
||||||
},
|
},
|
||||||
]
|
{
|
||||||
# 使用内置的 selection='single' 结合行点击事件实现背景高亮
|
"name": "note",
|
||||||
# 这样可以完全由 Python 事件逻辑控制,不依赖 CSS 伪类
|
"label": "备注",
|
||||||
refs["results_table"] = ui.table(
|
"field": "note",
|
||||||
columns=columns,
|
"align": "left",
|
||||||
rows=[],
|
}, ]
|
||||||
selection="single",
|
# 使用内置的 selection='single' 结合行点击事件实现背景高亮
|
||||||
row_key="original_name",
|
# 这样可以完全由 Python 事件逻辑控制,不依赖 CSS 伪类
|
||||||
).classes("w-full hide-selection-column")
|
refs["results_table"] = ui.table(
|
||||||
refs["results_table"].on("row-click", handle_row_click)
|
columns=columns,
|
||||||
|
rows=[],
|
||||||
|
selection="single",
|
||||||
|
row_key="original_name",
|
||||||
|
).classes("w-full hide-selection-column")
|
||||||
|
refs["results_table"].on("row-click", handle_row_click)
|
||||||
with ui.card().classes("w-full p-4 shadow-md"):
|
with ui.card().classes("w-full p-4 shadow-md"):
|
||||||
ui.label("拓扑可视化").classes("text-xl font-semibold mb-2")
|
ui.label("拓扑可视化").classes("text-xl font-semibold mb-2")
|
||||||
refs["plot_container"] = ui.column().classes("w-full items-center")
|
refs["plot_container"] = ui.column().classes("w-full items-center")
|
||||||
|
|||||||
11
main.py
11
main.py
@@ -18,6 +18,7 @@ plt.rcParams['axes.unicode_minus'] = False
|
|||||||
# 常量定义
|
# 常量定义
|
||||||
VOLTAGE_LEVEL = 66000 # 66kV
|
VOLTAGE_LEVEL = 66000 # 66kV
|
||||||
POWER_FACTOR = 0.95
|
POWER_FACTOR = 0.95
|
||||||
|
ELECTRICITY_PRICE = 0.4 # 元/kWh
|
||||||
|
|
||||||
# 1. 生成风电场数据(实际应用中替换为真实坐标)
|
# 1. 生成风电场数据(实际应用中替换为真实坐标)
|
||||||
def generate_wind_farm_data(n_turbines=30, seed=42, layout='random', spacing=800):
|
def generate_wind_farm_data(n_turbines=30, seed=42, layout='random', spacing=800):
|
||||||
@@ -224,8 +225,15 @@ def load_data_from_excel(file_path):
|
|||||||
system_params['voltage'] = val
|
system_params['voltage'] = val
|
||||||
elif 'factor' in key or '功率因数' in key:
|
elif 'factor' in key or '功率因数' in key:
|
||||||
system_params['power_factor'] = val
|
system_params['power_factor'] = val
|
||||||
|
elif 'price' in key or '电价' in key:
|
||||||
|
system_params['electricity_price'] = val
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# 设置默认电价(如果参数表中未提供)
|
||||||
|
if 'electricity_price' not in system_params:
|
||||||
|
system_params['electricity_price'] = ELECTRICITY_PRICE
|
||||||
|
|
||||||
if system_params:
|
if system_params:
|
||||||
print(f"成功加载系统参数: {system_params}")
|
print(f"成功加载系统参数: {system_params}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -1107,7 +1115,8 @@ def compare_design_methods(excel_path=None, n_clusters_override=None, interactiv
|
|||||||
|
|
||||||
voltage = system_params.get('voltage', VOLTAGE_LEVEL)
|
voltage = system_params.get('voltage', VOLTAGE_LEVEL)
|
||||||
power_factor = system_params.get('power_factor', POWER_FACTOR)
|
power_factor = system_params.get('power_factor', POWER_FACTOR)
|
||||||
print(f"使用的系统参数: 电压={voltage} V, 功率因数={power_factor}")
|
electricity_price = system_params.get('electricity_price', ELECTRICITY_PRICE)
|
||||||
|
print(f"使用的系统参数: 电压={voltage} V, 功率因数={power_factor}, 电价={electricity_price} 元/kWh")
|
||||||
|
|
||||||
# 准备三种电缆方案
|
# 准备三种电缆方案
|
||||||
# 原始 specs 是 5 元素元组: (section, capacity, resistance, cost, is_optional)
|
# 原始 specs 是 5 元素元组: (section, capacity, resistance, cost, is_optional)
|
||||||
|
|||||||
55
make_version.py
Normal file
55
make_version.py
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# make_version.py
|
||||||
|
import datetime
|
||||||
|
import os
|
||||||
|
|
||||||
|
def create_version_file():
|
||||||
|
# 1. 生成版本号 (示例:使用 年.月.日.0)
|
||||||
|
today = datetime.date.today()
|
||||||
|
# 格式:(2026, 1, 5, 0)
|
||||||
|
ver_tuple = (today.year, today.month, today.day, 0)
|
||||||
|
ver_str = f"{today.year}.{today.month}.{today.day}.0"
|
||||||
|
|
||||||
|
# 2. 定义版本信息结构 (PyInstaller 格式)
|
||||||
|
# 语言代码 2052 = 简体中文, 字符集 1200 = Unicode
|
||||||
|
content = f"""# UTF-8
|
||||||
|
VSVersionInfo(
|
||||||
|
ffi=FixedFileInfo(
|
||||||
|
filevers={ver_tuple},
|
||||||
|
prodvers={ver_tuple},
|
||||||
|
mask=0x3f,
|
||||||
|
flags=0x0,
|
||||||
|
OS=0x40004,
|
||||||
|
fileType=0x1,
|
||||||
|
subtype=0x0,
|
||||||
|
date=(0, 0)
|
||||||
|
),
|
||||||
|
kids=[
|
||||||
|
StringFileInfo(
|
||||||
|
[
|
||||||
|
StringTable(
|
||||||
|
u'080404b0',
|
||||||
|
[StringStruct(u'CompanyName', u'中能建西北院海上能源业务开发部'),
|
||||||
|
StringStruct(u'FileDescription', u'海上风电场集电线路设计优化系统'),
|
||||||
|
StringStruct(u'FileVersion', u'{ver_str}'),
|
||||||
|
StringStruct(u'InternalName', u'WindFarmOptimizer'),
|
||||||
|
StringStruct(u'LegalCopyright', u'Copyright (c) {today.year}'),
|
||||||
|
StringStruct(u'OriginalFilename', u'海上风电场集电线路设计优化系统.exe'),
|
||||||
|
StringStruct(u'ProductName', u'海上风电场集电线路设计优化系统'),
|
||||||
|
StringStruct(u'ProductVersion', u'{ver_str}')])
|
||||||
|
]),
|
||||||
|
VarFileInfo([VarStruct(u'Translation', [2052, 1200])])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
|
||||||
|
with open("version_info.txt", "w", encoding="utf-8") as f:
|
||||||
|
f.write(content)
|
||||||
|
|
||||||
|
# 3. 同时生成一个 python 文件供 gui.py 调用
|
||||||
|
with open("version.py", "w", encoding="utf-8") as f:
|
||||||
|
f.write(f'VERSION = "v{ver_str}"\n')
|
||||||
|
|
||||||
|
print(f"已生成版本信息文件: version_info.txt 和 version.py (版本: v{ver_str})")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
create_version_file()
|
||||||
23
pyproject.toml
Normal file
23
pyproject.toml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
[project]
|
||||||
|
name = "windfarm"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Add your description here"
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
dependencies = [
|
||||||
|
"ezdxf>=1.4.3",
|
||||||
|
"matplotlib>=3.10.8",
|
||||||
|
"networkx>=3.6.1",
|
||||||
|
"nicegui>=3.4.1",
|
||||||
|
"numpy>=2.4.0",
|
||||||
|
"openpyxl>=3.1.5",
|
||||||
|
"pandas>=2.3.3",
|
||||||
|
"pywebview>=6.1",
|
||||||
|
"scikit-learn>=1.8.0",
|
||||||
|
"scipy>=1.16.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[dependency-groups]
|
||||||
|
dev = [
|
||||||
|
"pyinstaller>=6.17.0",
|
||||||
|
]
|
||||||
0
使用说明/pandoc
Normal file
0
使用说明/pandoc
Normal file
@@ -1,7 +1,7 @@
|
|||||||
# 海上风电场集电线路设计优化软件 - 操作手册
|
# 海上风电场集电线路设计优化软件 - 操作手册
|
||||||
|
|
||||||
**文档版本:** v1.0
|
**文档版本:** v1.0
|
||||||
**适用对象:** 海上能源业务开发部 - 电气专业组
|
**适用对象:** 海上能源业务开发部 - 电气专业
|
||||||
**编制日期:** 2026年1月5日
|
**编制日期:** 2026年1月5日
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
海上风电集电线路作为风电机组与海上升压站的关键连接纽带,其优化设计对提升风电场全生命周期经济性及降低环境影响具有核心意义,不仅能通过拓扑与路由优化减少建设运维成本、降低线路损耗,还能为深远海、大容量风电场开发提供技术支撑。该优化工作面临拓扑与载流量多约束耦合的技术瓶颈,需综合运用数字化技术、先进优化算法进行应对。
|
海上风电集电线路作为风电机组与海上升压站的关键连接纽带,其优化设计对提升风电场全生命周期经济性及降低环境影响具有核心意义,不仅能通过拓扑与路由优化减少建设运维成本、降低线路损耗,还能为深远海、大容量风电场开发提供技术支撑。该优化工作面临拓扑与载流量多约束耦合的技术瓶颈,需综合运用数字化技术、先进优化算法进行应对。
|
||||||
|
|
||||||
本软件专为海上风电场内集电系统(35kV/66kV/110kV)设计,旨在通过多种先进的拓扑优化算法(如Esau-Williams、MST、旋转扫描法),辅助电气工程师快速完成集电线路的路径规划与经济性比选。
|
本软件专为海上风电场内集电系统(35kV/66kV/110kV)设计,旨在通过多种先进的拓扑优化算法(如Esau-Williams、MST、旋转扫描法),辅助电气专业快速完成集电线路的路径规划与经济性比选。
|
||||||
|
|
||||||
软件能够根据风机坐标、海缆载流量及造价数据,自动计算并生成线损最小、投资最优的接线方案,并支持一键导出 CAD 图纸和海缆长度。
|
软件能够根据风机坐标、海缆载流量及造价数据,自动计算并生成线损最小、投资最优的接线方案,并支持一键导出 CAD 图纸和海缆长度。
|
||||||
|
|
||||||
@@ -162,4 +162,4 @@ A: 软件算法以不超过额定载流量为约束条件(默认允许 100%
|
|||||||
A: 请双击鼠标滚轮(Zoom Extents)全屏显示。由于风机坐标通常是大地坐标(数值很大),如果 CAD 当前视口在 (0,0) 附近,可能会找不到图形。
|
A: 请双击鼠标滚轮(Zoom Extents)全屏显示。由于风机坐标通常是大地坐标(数值很大),如果 CAD 当前视口在 (0,0) 附近,可能会找不到图形。
|
||||||
|
|
||||||
---
|
---
|
||||||
**技术支持:** 海上能源业务开发部 - 数字化小组
|
**技术支持:** 海上能源业务开发部 - 杜孟远
|
||||||
|
|||||||
BIN
使用说明/使用说明.pdf
Normal file
BIN
使用说明/使用说明.pdf
Normal file
Binary file not shown.
Reference in New Issue
Block a user