# -*- coding: utf-8 -*-
"""生成 仿真集成台 单文件 HTML: 叙事 + 全部仿真入口 + 内嵌尾流图与动画。"""
import pathlib
import base64
_A = pathlib.Path(__file__).resolve().parent / "assets"
PNG = base64.b64encode((_A/"wake_real.png").read_bytes()).decode()
VIV = base64.b64encode((_A/"pain_viv.png").read_bytes()).decode()
YAWS = base64.b64encode((_A/"pain_yawslip.png").read_bytes()).decode()
PITCH= base64.b64encode((_A/"pain_pitch.png").read_bytes()).decode()
MP4 = base64.b64encode((_A/"wake_anim.mp4").read_bytes()).decode()
G = "http://127.0.0.1:28084"
L = "file:///Users/yuanying/guanlan-rudong-v2/outputs/rudong/windscada/_demo/sim"
ARCH_SVG = ''''''
def card(title, kind, kcls, model, state, scls, desc, href, meta):
return f'''
{title}{kind}
机型 {model}{state}
{desc}
{meta}
'''
SIMS_A = "".join([
card("四系统联调 · 合页","正演","kf","4 MW 海上","参数=实机回读","s-meas",
"偏航、传动链与功率、发电机与热管理、变桨轮毂液压,十七个面板在一页里联动。",
f"{G}/sim/sys/0_四系统合页.html","可拖滑块 · 六项失效注入"),
card("偏航系统","正演","kf","4 MW 海上","参数=实机回读","s-meas",
"风向标滤波 → 对风偏差 → 死区 → 刹车泄压 → 起偏 → 停止容差 → 扭缆累积。",
f"{G}/sim/sys/1_偏航系统.html","注入:静态误差 / 风向标卡死 / 驱动降速"),
card("传动链与功率","正演","kf","4 MW 海上","参数=实机回读","s-meas",
"转速-功率十五点表、桨距调度表、3P 共振禁带,出厂默认与本台整定双曲线同图。",
f"{G}/sim/sys/2_传动链与功率.html","注入:风速仪偏低 / 偏高 / 卡死"),
card("发电机与热管理","正演","kf","4 MW 海上","参数=实机回读","s-meas",
"定子温度与保护裕度、冷却链、告警线,温度条实时跟随。",
f"{G}/sim/sys/3_发电机与热管理.html","注入:散热劣化 / 冷却风机 / 传感器"),
card("变桨与轮毂液压","正演","kf","4 MW 海上","参数=实机回读","s-meas",
"变桨闭环、轮毂压力、蓄能器充放循环,分段增益逐台对比。",
f"{G}/sim/sys/4_变桨轮毂液压.html","注入:润滑 / 跟踪超差 / 校准 / 棘爪"),
card("整机联调台 · 4 MW","正演","kf","4 MW 全功率","控制核心层参数","s-meas",
"主控、变桨、变流器三者配合的联调过程,控制核心层三百七十九项参数完整接入。",
f"{L}/整机联调台_4MW.html","可调风速与转速 · 实时曲线"),
card("整机联调台 · 1.5 MW","正演","kf","1.5 MW 双馈","控制核心层参数","s-meas",
"另一功率代际的联调:主控、变桨、变频器,含状态码、刹车程序与降容逻辑。",
f"{L}/整机联调台_1.5MW.html","可与 4 MW 对照看代际差异"),
])
SIMS_B = "".join([
card("变桨液压回路仿真台","正演 · 图纸级","kf","4 MW 海上","按原厂图纸搭建","s-meas",
"一个油箱、变桨大站与高速轴制动两条回路、两组蓄能器。可注入失氮、外漏、泵排量下降。",
f"{L}/U6_变桨液压仿真台.html","实时看派生指标与逐循环进油量"),
card("传动链实际运行回放 · 38 台","回放","kr","4 MW 海上","实测 · 一个字节不造","s-meas",
"三十八台机组二十四小时逐分钟真实记录,配十六台在问题窗的真实振动波形与频谱。",
f"{L}/如东传动链实际运行诊断_单文件版.html","同一触发时刻 · 可播放 · 可切机组"),
card("液压公共站健康报告","实测判据","kr","4 MW 海上","实测","s-meas",
"系统总容变分解、两组蓄能器各自的角色、逐台健康分级。",
f"{L}/U6_液压公共站健康报告_客户版.html","仿真台标定判据的产物"),
card("整机综合诊断与风险评估","实测判据","kr","4 MW 海上","实测 · 双模型审","s-meas",
"主轴冲击深挖修订版,逐台逐系统判级。",
f"{L}/如东海上风电场_整机综合诊断与风险评估_主轴冲击深挖修订版V2.1.html","修订版"),
])
SIMS_D = "".join([
card("涡激共振模拟器","正演 · 教学示范","kf","十二款机型预设","⚠ 频率与阻尼=标度律外推","s-syn",
"可调风速、塔高、叶轮直径、偏航角、转速,实时看塔架与叶片的固有频率、涡脱频率与共振禁带。"
"涵盖塔架涡激、叶片涡激、偏航失速颤振、启动穿越禁带四种情形。"
"核过来源:几何参数取自公开机型库(可信),但固有频率与阻尼比是统一标度律外推、无一机型有实测模态"
"——所以这台只教机理趋势,不可用它的数值下任何结论。",
f"{L}/涡激共振模拟器.html","几何取公开源;无逐机型实测模态 → 只看趋势不看数值"),
card("涡激实测核验","实测","kr","1.5 MW 陆上 × 9 台","实测秒级","s-meas",
"抗涡激动作标志一次未触发。本页回答的是:零触发到底是真没事,还是监测面根本没在工作。",
f"{L}/涡激实测核验.html","每台 43200 秒 · 活通道 vs 死通道对比"),
card("运行形态塌陷 · 动态三维","实测 · 可旋转","kr","4 台 × 18 月 × 15 风速档","实测 + 算法产物","s-meas",
"横轴风速档、纵轴月份、高度是健康裕度。绿色曲面是正常,裕度掉到零平面以下就是形态塌陷 ——"
"在图上表现为从曲面往下扎的一口井。两种算法可切换对照。"
"深度数值不可跨算法比(阈值一个 0.754 一个 0.034),可比的只有位置模式。",
f"{L}/运行形态塌陷_动态三维.html","可旋转缩放 · 四台并排 · 真实最深值如实报"),
card("偏航滑移事件回放","回放","kr","单台机组","实测事件","s-meas",
"制动压不住风载,机舱在无偏航指令下被推着走。可逐事件回放机舱位置与对风偏差。",
f"{L}/偏航滑移事件回放.html","该台全窗四十四次 · 最深一次 42.3°"),
card("变流器故障仿真","注入","ka","1.5 MW 陆上","⚠ 波形为合成","s-syn",
"十千赫兹逐样本算物理量,保护判据真的跑在波形上,越限才爆码,码按事件记录格式列出。"
"改一个定值滑块,爆出来的码就会变。",
f"{L}/变流器故障仿真.html","八类场景 · 电网跌落 / Crowbar 拒动 / IGBT 开路 / 水冷失效"),
card("变桨故障仿真","注入","ka","1.5 MW 陆上","⚠ 波形为合成","s-syn",
"同一套做法用在变桨系统:参数可调、判据在波形上跑、越限爆码。",
f"{L}/变桨故障仿真.html","用于训练判读与验证判据(known-answer)"),
])
SIMS_C = "".join([
card("整机三维拆装工作台","结构","ks","4 MW 海上","实物结构","s-meas",
"五十八个部件的爆炸图:主轴与轴承、齿轮箱及附件、发电机与冷却、三套集中润滑、"
"变桨泵站与阀块、偏航驱动与轴承、机架、滑环……逐件可拆可看。",
f"{G}/viewer/unit-workbench.html","可旋转 · 可拆解 · 逐件说明"),
card("故障分布三维视图","实测","kr","多台 × 九系统","实测事件统计","s-meas",
"机组 × 系统 × 月份三个维度一起看,气泡大小为停机时长。可旋转、可缩放、可按系统筛。",
f"{L}/故障分布三维视图.html","离线可用(图形库已本地化)"),
card("振动诊断 · CMS","实测","kr","4 MW 海上","实测","s-meas",
"频谱、包络、特征频率与告警分级,逐台逐测点。",
f"{G}/cms/?theme=light","客户版界面"),
card("综合详细分析工作台","实测","kr","4 MW 海上","实测","s-meas",
"全场逐台逐系统的分析结果与证据链。",
f"{G}/detail/v2","在线系统"),
])
HTML = f'''
风电机组仿真集成台
观
观澜 · 风电机组仿真集成台GUANLAN SIMULATION HUB
离线运行 · 无需网络
一个入口,全部仿真
从图纸到回路,从信号到工单
二十一个仿真台、回放台与结构台集中在这一页。每一个都标了它的数从哪来 ——
算出来的(按参数与图纸正演)、测出来的(真实运行记录回放)、还是结构。
这条分界是所有诊断的第一课。
01 · 整体架构
两个模块,可分可合,看预算
数字仿真回答「现场实际发生了什么」,半实物回答「控制器本来该怎么响应」。
两个模块各自都能单独成立:只买数字,七篇课里六篇照上;只买半实物,能做控制器测试但培训内容基本是空的。
组合起来才多出第三个问题的答案——现场的样子和设计的样子,差在哪。这是唯一值得为组合多付钱的理由。
⚠ 组合形态的那条接缝(实测时序 → 测试序列 → 真控制器复现)
至今一次都没跑通过。它是本方案技术风险最高的一环,不应当作既成能力。只买数字模块则不承担此风险。
{ARCH_SVG}
02 · 整体价值
它把三件看不见的事变成看得见的
价值一
故障在信号上长什么样
现场三年遇不到的故障,这里可以反复注入观察。蓄能器丢气、外漏、泵磨损 —— 三者签名方向各不相同,
所以能分得开。已有六项注入全部对应真实告警码,不是编的动画。
价值二
手册和真机的差距
整机参数回读之后才发现,这台机器有二十四项现场整定值和出厂默认不一样,
其中转速-功率曲线九个点全被改过。手册上那条曲线,它并没有在跑。
两条曲线同图一画,这件事一屏说完。
价值三
判据到底准不准
判据不是写完就算数。先把已知答案的故障注进真实数据,看它判不判得出、会不会误报 ——
一百六十四个场景考过,才准上机器。这一步别人通常跳过,我们不跳。
还有一层价值是结构性的:同一套口径能罩住不同厂商、不同功率代际的机器。
一个场里跑着三家整机厂的机组,没有统一尺子就没法横比、没法排优先级 —— 这正是我们地基那层在解决的问题。
03 · 我们能做什么 · 控制律
机器是怎么被控制的
参数来自整机控制器实机回读。图上同时画出厂默认曲线与本台现场整定曲线,低转速段肉眼可见地分开。
{SIMS_A}
03 · 我们能做什么 · 回路与回放
按图纸搭回路,用实测验判据
判据不是从数据里拟合出来的,是先在物理上算出来、再用整场实测反过来验证的。
{SIMS_B}
03 · 我们能做什么 · 痛点专项
涡激、偏航滑移、故障爆码,各有各的台子
机理归机理、实测归实测、合成归合成 —— 每张卡片都标了机型和数据状态,一眼能分清。
{SIMS_D}
03 · 我们能做什么 · 结构与在线
拆得开,也看得见现在
{SIMS_C}
03 · 我们能做什么 · 场级
整个风场一起看
单台之外还有场级:机位之间互相遮挡。下面用的是一个真实山地风场的九十台实际机位,
风向分布来自该场一百二十一万条实测十分钟记录。坐标已做刚性变换脱敏 —— 相对几何不变,所以尾流物理为真。
主导风向 165°(占全年 33.5%)下的尾流场。标注为该风向下受尾流最深的三台。
边界:平坦地形假设、推力曲线为通用示意值 → 只看相对形态与排序,不报绝对损失。引擎 PyWake(丹麦技术大学)。
动态:风向从 90° 扫到 270°(覆盖约九成的时间),看尾流在整个场里横扫。右下风玫瑰为实测分布。
03 · 我们能做什么 · 行业痛点
三个「看着没事、后果很重」的问题
共同点是:站在塔下看不出来,在常规报表上也不显眼,但都实打实吃电量、吃寿命,甚至吃安全。
下面每一张都标了哪部分是实测、哪部分是模型、哪部分引文献。
涡激振荡 —— 风吹过塔筒周期性脱落旋涡,脱落频率撞上塔筒固有频率就进入锁频,振动自己放大自己。
两个反直觉之处:临界风速落在很常见的风速段,不是极端天气;最危险的是吊装期和不带叶片的停机,因为叶轮转动提供的气动阻尼没了。
本图为工程经验模型(涡脱频率 + 锁频带 + Scruton 数),非 CFD、非气弹耦合,参数为通用示意值。
偏航滑移 —— 制动力矩压不住风载力矩,机舱在没有任何偏航指令的情况下被风推着走。
上排是五十台机组的实测事件:一半机组一次没滑,问题集中在少数台,最深一次滑了四十二度,而且逐月分布有明显断点。
下排是三种在信号上长得很像的现象,判滑移必须四门同时成立,缺一就会误判。
上排为实测统计(台号已重编);下排为合成教学信号。
变桨角度不一致 —— 三个叶片桨距不一致,气动推力不再三重对称,合力矩多出一个每转一圈来一次的分量,
直接打在轮毂、主轴和塔架上。中间那张是真实机群的塔筒 1P 筛查:四十二台里只挑出两台,这正是机群相对筛查该有的样子。
机理为正演(相对量);筛查为实测;电量与寿命后果因运行数据无载荷通道,全部引文献,本模型不自算。
04 · 培训编排
一台机器,一条链走完
前置一篇加正课六篇。每一篇的落点是"学员能自己做什么",不是"我们讲了什么"。
前置
这些东西各能信到什么程度
放最前面,不是放附录。三个标签贯穿全程:数从哪来、保真到哪一档、结论能用到什么级别。
一
认识这台机器
五十八个部件的爆炸图,再叠一层传动链运动学 —— 风轮转一圈,齿轮箱那头转一百一十九圈多。
二
它是怎么被控制的
转矩控制怎么追最优叶尖速比、变桨怎么在额定以上稳功率、偏航死区滞环怎么定。
三
真实世界里它长什么样
整场逐台回放,配真实振动波形与频谱。教一条最容易踩的口径:同步派生转矩不是扭矩传感器实测。
四
它会怎么坏 —— 核心
现场罕见的故障,这里可以反复注入观察。已有六项注入全部对应真实告警码;新增涡激振荡与偏航滑移两个专题。
五
怎么判、怎么修、怎么验
判据 → 定向清单加排除清单 → 工单 → 改后同工况复核。排除清单不占改造预算。
六
换一台机器怎么办
换一家整机厂、换一个功率代际,这套判据与流程怎么搬过去。
部件域判据
10个
变桨 · 静态偏航 · 动态偏航 · 部件温度 · 振动频谱 · 液压站 · 限电识别 · 功率曲线 · 欠发归因 · 特性曲线
场级字段契约
71份
每份是一个风场的字段语义定稿,覆盖十九家可辨识整机厂
判据靶场场景
164个
已知答案的注入与回放场景,判据先在这里考过才准上机
判据先在一百六十四个已知答案上考过,才准上你们的机器。
工具库才是壁垒 —— 模型只是调度器。
'''
_OUT = pathlib.Path(__file__).resolve().parents[2] / "outputs/rudong/windscada/_demo/sim"
pathlib.Path(_OUT/"仿真集成台.html").write_text(HTML, encoding="utf-8")
print("written 仿真集成台.html")