i18n.py 7.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. # -*- coding: utf-8 -*-
  2. """显示层中文化 (2026-08-25 用户令: 所有英文翻译, 故障代码转译专业中文).
  3. 权威链: 故障码 = 西门子对译表(广核如海本项目清单优先, 3839码, reference/rudong/alarm_code_cn.json)
  4. + 专业措辞覆盖层 (表内机翻腔改写; 覆盖≠改义, 原表文与英文保留在 data 里可溯).
  5. 通道名 = 契约位号 → 专业中文 (身份按既有指纹判定; 不确定处保位号后缀防误认)."""
  6. try:
  7. from app_common.app_common_guanlan.api import install_root as _install_root
  8. except ImportError: # 极端兜底(包结构异常时按位置上跳)
  9. from pathlib import Path as _P
  10. def _install_root(_f): return _P(_f).resolve().parents[3]
  11. import json, pathlib, re
  12. _REF = _install_root(__file__) / 'reference/rudong/alarm_code_cn.json'
  13. _TABLE = json.loads(_REF.read_text(encoding='utf-8')) if _REF.exists() else {}
  14. # 专业措辞覆盖 (常显码; 原则: 部件-现象-性质, 保留西门子语境词 DG/FRT/UPS 的行业通译)
  15. PRO = {
  16. '3225': '液压监控·轮毂(变桨)压力偏高', '3224': '液压监控·系统油压偏高', '3130': '变桨轴承润滑(执行中)',
  17. '3411': '蓄能器A缸检测超时', '3412': '蓄能器B缸检测超时', '3413': '蓄能器C缸检测超时',
  18. '7100': '变桨液压油温过高', '7101': '液压油位异常', '7102': '液压油温异常',
  19. '7103': '液压滤芯警告(压差)', '7104': '液压滤芯故障(压差)', '7106': '变桨泵运行超时停机',
  20. '9306': '偏航制动蓄能器压力过低',
  21. '10100': '偏航电机过热', '10104': '偏航位置传感器故障', '10105': '自动解缆停机',
  22. '10113': '偏航制动液压压力异常', '10125': '偏航变流器警告过多', '10201': '偏航轴承润滑无法执行',
  23. '10400': '偏航失败-等待', '10401': '偏航失败-停止', '7122': '偏航液压油位低', '1012': '偏航限位传感器动作',
  24. '8108': 'FT1超声波风速计故障', '8110': 'FT1超声波风速计通讯故障',
  25. '8184': '多风速计报警激活(冗余切换)', '8185': '多风向标报警激活(冗余切换)',
  26. '8186': '一次风速计故障', '8187': '一次风向标失效', '8171': '二次风速计强制投入',
  27. '13902': '变流器跳闸(自动重启)', '13905': '变流器降功率运行(DG)', '5122': '电网故障穿越(FRT)动作',
  28. '19170': 'ABB变流器内部通讯故障(INU-AFF8)', '19024': 'ABB变流器PU通讯故障(INU-5681)',
  29. '63003': '电网停电停机', '63004': 'UPS电池电压低', '8297': '机舱环境温度超限',
  30. '1001': '手动停机', '1015': '手动待机停机', '1020': '就地操作模式', '1007': '远程停机(业主)', '1008': '远程停机(西门子)',
  31. '2700': '塔筒频率外部允许窗口', '2006': '场级能量限制(西门子DG)',
  32. }
  33. def alarm_label(code, rawtext=''):
  34. code = str(code)
  35. if code in PRO: return PRO[code]
  36. t = _TABLE.get(code, {}).get('cn', '')
  37. return t or (str(rawtext).strip() or f'码{code}')
  38. # 通道位号 → 专业中文 (stem 级; 身份=契约命名指纹, 前/后与 DE/NDE 按既有配对判定)
  39. STEM = {
  40. 'MBearHTm': '前主轴承温度(轮毂侧)', 'MBearGTm': '后主轴承温度(齿轮箱侧)',
  41. 'GeOilTmp': '齿轮箱油温', 'IMSGenTm': '齿轮箱中速轴温度(发电机侧)', 'IMSRotTm': '齿轮箱中速轴温度(转子侧)',
  42. 'HSGenTmp': '齿轮箱高速轴温度(发电机侧)', 'HSRotTmp': '齿轮箱高速轴温度(转子侧)',
  43. 'GFilB1Tm': '齿轮箱滤芯加热带B1温度', 'GFilB2Tm': '齿轮箱滤芯加热带B2温度', 'GFilB3Tm': '齿轮箱滤芯加热带B3温度',
  44. 'BrkTmpGn': '机械刹车温度(发电机侧)', 'BrkTmpGr': '机械刹车温度(齿轮箱侧)',
  45. # 端别定案 (2026-08-26, 官方证据: 西门子 WTC-3 IO表 IO_V30_VS_170809_R1.00 第2页 IOHandle1 X6=GenBeRTm'DE' X8=GenBeGTm'NDE'; 振动线跨会话质疑触发, 我方原标注反了已改; 物理旁证 R端全场高10.1K 38/38)
  46. 'GenBeGTm': '发电机非驱动端(NDE)轴承温度', 'GenBeRTm': '发电机驱动端(DE)轴承温度',
  47. 'Gen1U1Tm': '发电机定子绕组温度U相', 'Gen1V1Tm': '发电机定子绕组温度V相', 'Gen1W1Tm': '发电机定子绕组温度W相',
  48. 'ConvWTmp': '变流器冷却水温度', 'TrafoTMa': '变压器绕组最高温度', 'TraOilTF': '变压器油温', 'TraRooTF': '变压器室温度',
  49. 'A1ExtTmp': 'A1柜排风温度', 'A21IntTm': 'A21柜内温度', 'A3LefTmp': 'A3柜左侧温度', 'A3RigTmp': 'A3柜右侧温度',
  50. 'NacelTmp': '机舱温度', 'HubTemp': '轮毂温度', 'AmbieTmp': '环境温度', 'HydOilTm': '液压油温',
  51. 'HydPress_band': '变桨液压压力摆幅', 'HydPress': '变桨液压系统压力', 'YawPress': '偏航制动压力',
  52. 'YawLubPu': '偏航润滑泵', 'Y1LubPis': '偏航润滑柱塞', 'MBLubPis': '主轴承润滑柱塞', 'GBLubPis': '齿轮箱润滑柱塞',
  53. 'GenLubPu': '发电机润滑泵', 'HubLubPu': '轮毂润滑泵(变桨轴承)', 'PitchPum': '变桨液压泵使能',
  54. 'LubPistA': '变桨润滑柱塞A', 'LubPistB': '变桨润滑柱塞B', 'LubPistC': '变桨润滑柱塞C',
  55. 'HydLevel': '液压油位开关', 'HydrFilt': '液压滤芯开关', 'ScYawOpe': '偏航动作(运行标志)',
  56. 'TORYaw': '扭缆正常位', 'Windvane': '风向标信号', 'WindFauS': '风传感故障计数S路', 'WindFauT': '风传感故障计数T路',
  57. 'PriAnemo': '一次风速计', 'SecAnemo': '二次风速计(判别用)', 'ActualWindDirection': '风向(合成口径)',
  58. 'MainSRpm': '主轴转速', 'GenRpm': '发电机转速', 'ActPower': '有功功率', 'PowerRef': '功率给定', 'PowerRed': '功率削减位',
  59. 'PitcPosA': '桨叶A桨距角', 'PitcPosB': '桨叶B桨距角', 'PitcPosC': '桨叶C桨距角',
  60. 'PitchRef_BladeA': '桨叶A桨距角给定', 'PitchRef_BladeB': '桨叶B桨距角给定', 'PitchRef_BladeC': '桨叶C桨距角给定',
  61. 'kWG1TotE': '发电量计数(出口)', 'kWG1TotI': '受电量计数', 'kWG1Tot': '发电量计数',
  62. 'ScComErr': '主控通讯错误计数', 'ScEnvErr': '主控环境错误计数', 'ScGrdErr': '主控电网错误计数', 'ScTurErr': '主控机组错误计数',
  63. }
  64. SUFFIX = {'_mean': '均值', '_max': '最大', '_min': '最小', '_stddev': '标准差', '_endvalue': '末值',
  65. '_accum': '累计', '_counts': '次数', '_timeon': '接通时长'}
  66. TOKEN = [('×fleet', '×全场'), ('vs fleet', 'vs 全场'), ('fleet中位', '全场中位'), ('fleet', '全场'),
  67. ('dev ', '偏差 '), ('dev_w', '偏差'), ('ws偏置', '风速计偏置'), ('rank', '名次'), ('duty', '运行时长')]
  68. _STEMS = sorted(STEM, key=len, reverse=True)
  69. def ch_cn(col, with_tag=True):
  70. """契约列名 → 专业中文 (可带位号溯源)."""
  71. base = col
  72. for p in ('tmp_wtc_', 'prs_wtc_', 'dot_wtc_', 'din_wtc_', 'cnt_wtc_', 'flg_wtc_', 'tur_wtc_', 'grd_wtc_'):
  73. base = base.replace(p, '')
  74. suf = ''
  75. for k, v in SUFFIX.items():
  76. if base.endswith(k):
  77. base = base[: -len(k)]; suf = v; break
  78. cn = STEM.get(base)
  79. if not cn: return col
  80. nm = cn + (f'·{suf}' if suf else '')
  81. return f'{nm} [{base}]' if with_tag else nm
  82. def humanize(s):
  83. """依据/标题串中的位号与英文 token → 专业中文 (显示层, 不改数据)."""
  84. if not isinstance(s, str): return s
  85. for st in _STEMS:
  86. if st in s: s = s.replace(st, STEM[st])
  87. for a, b in TOKEN:
  88. if a in s: s = s.replace(a, b)
  89. return s