Auto_diag.py 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124
  1. import numpy as np
  2. import pandas as pd
  3. from typing import List
  4. import json
  5. from sqlalchemy import create_engine
  6. import math
  7. from app.config import dataBase
  8. from app.database import get_engine
  9. from app.logger import logger
  10. from app.services.DiagnosisLib import DiagnosisLib
  11. class Auto_diag:
  12. def __init__(self, ids: List[int], wind_code: str, engine_code: str):
  13. """
  14. 初始化诊断类
  15. 参数:
  16. ids: 数据ID列表
  17. wind_code: 风场编号
  18. engine_code: 风机编号
  19. """
  20. self.ids = ids
  21. self.wind_code = wind_code
  22. self.engine_code = engine_code
  23. self.myDiagnosisLib = DiagnosisLib()
  24. self.diagnosis_results = [] # 存储所有诊断结果
  25. self.bearing_frequencies = {} # 存储特征频率
  26. self.teeth_count = {} # 存储齿数
  27. # 从数据库加载振动数据
  28. self.load_vibration_data()
  29. # 计算转速传动比
  30. self.calculate_speed_ratio()
  31. # 提取轴承参数、齿轮参数 计算特征频率
  32. self.Characteristic_Frequency()
  33. # 计算频谱
  34. self.calculate_spectrums()
  35. def load_vibration_data(self):
  36. """从数据库中获取振动加速度数据"""
  37. try:
  38. engine = get_engine(dataBase.DATA_DB)
  39. with engine.connect() as conn:
  40. table_name = self.wind_code + '_wave'
  41. # 将所有id拼接到SQL语句中,一次性查询所有数据
  42. ids_str = ','.join(map(str, self.ids))
  43. sql = f"SELECT * FROM {table_name} WHERE id IN ({ids_str})"
  44. df = pd.read_sql(sql, conn)
  45. self.df_data = df
  46. # 提取公共参数
  47. self.fspd = self.df_data['rotational_speed'].astype(float).values # 转速
  48. self.fs_acc = self.df_data['sampling_frequency'].astype(float).values # 采样频率
  49. self.mesure_point_names = self.df_data['mesure_point_name'].values
  50. # 处理加速度数据
  51. self.Acc = []
  52. self.t_acc = []
  53. for i, row in self.df_data.iterrows():
  54. measure_data_str = row['mesure_data']
  55. try:
  56. measure_data_list = json.loads(measure_data_str)
  57. acc_data = np.array(measure_data_list, dtype=np.float32)
  58. except json.JSONDecodeError:
  59. stripped_str = measure_data_str.strip('[]')
  60. measure_data_list = [float(x.strip()) for x in stripped_str.split(',') if x.strip()]
  61. acc_data = np.array(measure_data_list, dtype=np.float32)
  62. self.Acc.append(acc_data)
  63. # 使用转换后的数值类型计算时间轴
  64. self.t_acc.append(np.arange(0, len(acc_data) / self.fs_acc[i], 1 / self.fs_acc[i]))
  65. except Exception as e:
  66. raise Exception(f"Failed to load vibration data: {str(e)}")
  67. finally:
  68. engine.dispose()
  69. def calculate_spectrums(self):
  70. """计算各种频谱"""
  71. logger.info("计算频谱")
  72. self.fAcc = []
  73. self.AccSpec = []
  74. self.VelSpec = []
  75. self.gE_10 = []
  76. self.fAcc_gE = []
  77. self.gESpec_10 = []
  78. if self.fs_acc[0] < 12800:
  79. logger.info("当前采集频率不适合进行诊断分析")
  80. raise ValueError("当前采集频率不适合进行诊断分析")
  81. for i, acc in enumerate(self.Acc):
  82. # 获取当前 id 对应的采样频率
  83. fs_acc = self.fs_acc[i]
  84. fmax_acc = fs_acc / 2.56
  85. logger.info(fs_acc)
  86. logger.info(acc)
  87. lowcut = 500 # 最低值是固定的 /51.2
  88. highcut = fs_acc / 2.56
  89. # 计算振动加速度频谱
  90. [f, spec] = self.myDiagnosisLib.Spectrum(acc, fs_acc)
  91. self.fAcc.append(f)
  92. self.AccSpec.append(spec)
  93. # 计算振动速度频谱
  94. fCut = 0.1
  95. vel_spec = self.myDiagnosisLib.FreqIntegration(spec, fmax_acc, fCut)
  96. self.VelSpec.append(vel_spec)
  97. # 计算加速度包络频谱
  98. order = 6
  99. acc_band = self.myDiagnosisLib.BandPassButter(acc, lowcut, highcut, fs_acc, order)
  100. fmax_gE_10 = 1000
  101. DownSampleRate = int(fs_acc / 2.56 / fmax_gE_10) # 降采样
  102. gE = self.myDiagnosisLib.EnvLopInTime(acc_band, DownSampleRate, Method="SKF")
  103. self.gE_10.append(gE)
  104. fs_gE_10 = 2.56 * fmax_gE_10
  105. [f, spec] = self.myDiagnosisLib.Spectrum(gE, fs_gE_10)
  106. self.fAcc_gE.append(f)
  107. self.gESpec_10.append(spec)
  108. def Unbalance_diag(self):
  109. """不平衡诊断"""
  110. logger.info("不平衡诊断")
  111. status_codes = []
  112. for i in range(len(self.ids)):
  113. ShaftSpd = self.fspd[i] * self.speed_ratio
  114. if ShaftSpd == 0:
  115. status_codes.append(-1)
  116. continue
  117. try:
  118. fs_acc = self.fs_acc[i]
  119. fmax_vel = 1000
  120. # fmax_vel =max(1000,fs_acc/2.56)
  121. logger.info('ShaftSpd', ShaftSpd)
  122. fTarget = ShaftSpd / 60
  123. logger.info('fTarget', fTarget)
  124. numHarmonics = 4
  125. fRange = 0.05
  126. fRangeMode = "Per"
  127. Detection = "RMS"
  128. logger.info(self.VelSpec[i])
  129. try:
  130. Vel_RunningSpd_HM = self.myDiagnosisLib.FixedFreqFeature(
  131. self.VelSpec[i], fmax_vel, fTarget, fRange, fRangeMode, Detection, numHarmonics
  132. )
  133. except Exception as e:
  134. # logger.info(f"计算 Vel_RunningSpd_HM 时出错: {e}")
  135. Vel_RunningSpd_HM = [0] * (numHarmonics + 1)
  136. logger.info('Vel_RunningSpd_HM', Vel_RunningSpd_HM)
  137. Vel_alert_mmsRMS = 4 # 速度报警阈值
  138. Vel_danger_mmsRMS = 7 # 速度危险阈值
  139. defectType = 'Unbalance'
  140. try:
  141. detection, severity = self.myDiagnosisLib.RunningSpd_Fault_Diag(
  142. Vel_RunningSpd_HM, Vel_alert_mmsRMS, Vel_danger_mmsRMS, defectType
  143. )
  144. except Exception as e:
  145. detection = False
  146. severity = 0
  147. logger.info("severity", severity)
  148. if not detection:
  149. status_code = 0
  150. elif severity < 6:
  151. status_code = 1
  152. else:
  153. status_code = 2
  154. except Exception as e:
  155. status_code = 0
  156. status_codes.append(status_code)
  157. logger.info("status_code", status_code)
  158. # 返回结果和统计信息
  159. return {
  160. "type": "Unbalance",
  161. "results": status_codes,
  162. "statistics": {
  163. "max_status": max(status_codes),
  164. "count_0": status_codes.count(0),
  165. "count_1": status_codes.count(1),
  166. "count_2": status_codes.count(2)
  167. }
  168. }
  169. def Misalignment_diag(self):
  170. """不对中诊断"""
  171. status_codes = []
  172. logger.info("不对中诊断")
  173. for i in range(len(self.ids)):
  174. ShaftSpd = self.fspd[i] * self.speed_ratio
  175. if ShaftSpd == 0:
  176. status_codes.append(-1)
  177. continue
  178. try:
  179. fs_acc = self.fs_acc[i]
  180. fmax_vel = 1000
  181. # fmax_vel =max(1000,fs_acc/2.56)
  182. fTarget = ShaftSpd / 60
  183. numHarmonics = 4
  184. fRange = 0.05
  185. fRangeMode = "Per"
  186. Detection = "RMS"
  187. logger.info('ShaftSpd', ShaftSpd)
  188. logger.info('fTarget', fTarget)
  189. try:
  190. Vel_RunningSpd_HM = self.myDiagnosisLib.FixedFreqFeature(
  191. self.VelSpec[i], fmax_vel, fTarget, fRange, fRangeMode, Detection, numHarmonics
  192. )
  193. except Exception as e:
  194. # logger.info(f"计算 Vel_RunningSpd_HM 时出错: {e}")
  195. Vel_RunningSpd_HM = [0] * (numHarmonics + 1)
  196. logger.info('Vel_RunningSpd_HM', Vel_RunningSpd_HM)
  197. Vel_alert_mmsRMS = 4 # 速度报警阈值
  198. Vel_danger_mmsRMS = 7 # 速度危险阈值
  199. try:
  200. defectType = 'Misalignment'
  201. detection, severity = self.myDiagnosisLib.RunningSpd_Fault_Diag(
  202. Vel_RunningSpd_HM, Vel_alert_mmsRMS, Vel_danger_mmsRMS, defectType
  203. )
  204. except Exception as e:
  205. detection = False
  206. severity = 0
  207. logger.info('severity', severity)
  208. if not detection:
  209. status_code = 0
  210. elif severity < 6:
  211. status_code = 1
  212. else:
  213. status_code = 2
  214. except Exception as e:
  215. status_code = 0
  216. status_codes.append(status_code)
  217. return {
  218. "type": "Misalignment",
  219. "results": status_codes,
  220. "statistics": {
  221. "max_status": max(status_codes),
  222. "count_0": status_codes.count(0),
  223. "count_1": status_codes.count(1),
  224. "count_2": status_codes.count(2)
  225. }
  226. }
  227. def Looseness_diag(self):
  228. """松动诊断"""
  229. status_codes = []
  230. logger.info("松动诊断")
  231. for i in range(len(self.ids)):
  232. ShaftSpd = self.fspd[i] * self.speed_ratio
  233. if ShaftSpd == 0:
  234. status_codes.append(-1)
  235. continue
  236. try:
  237. fs_acc = self.fs_acc[i]
  238. fmax_vel = 1000
  239. # fmax_vel =max(1000,fs_acc/2.56)
  240. fTarget = ShaftSpd / 60
  241. numHarmonics = 4
  242. fRange = 0.05
  243. fRangeMode = "Per"
  244. Detection = "RMS"
  245. logger.info('ShaftSpd', ShaftSpd)
  246. logger.info('fTarget', fTarget)
  247. try:
  248. Vel_RunningSpd_HM = self.myDiagnosisLib.FixedFreqFeature(
  249. self.VelSpec[i], fmax_vel, fTarget, fRange, fRangeMode, Detection, numHarmonics
  250. )
  251. except Exception as e:
  252. # logger.info(f"计算 Vel_RunningSpd_HM 时出错: {e}")
  253. Vel_RunningSpd_HM = [0] * (numHarmonics + 1)
  254. logger.info('Vel_RunningSpd_HM', Vel_RunningSpd_HM)
  255. Vel_alert_mmsRMS = 4 # 速度报警阈值
  256. Vel_danger_mmsRMS = 7 # 速度危险阈值
  257. try:
  258. defectType = 'Looseness'
  259. detection, severity = self.myDiagnosisLib.RunningSpd_Fault_Diag(
  260. Vel_RunningSpd_HM, Vel_alert_mmsRMS, Vel_danger_mmsRMS, defectType
  261. )
  262. except Exception as e:
  263. detection = False
  264. severity = 0
  265. logger.info('severity', severity)
  266. if not detection:
  267. status_code = 0
  268. elif severity < 6:
  269. status_code = 1
  270. else:
  271. status_code = 2
  272. except Exception as e:
  273. status_code = 0
  274. status_codes.append(status_code)
  275. return {
  276. "type": "Looseness",
  277. "results": status_codes,
  278. "statistics": {
  279. "max_status": max(status_codes),
  280. "count_0": status_codes.count(0),
  281. "count_1": status_codes.count(1),
  282. "count_2": status_codes.count(2)
  283. }
  284. }
  285. def Bearing_diag(self):
  286. """轴承诊断"""
  287. logger.info("轴承诊断")
  288. # Vel_RunningSpd_HM,生成转频的1X-5X的倍频值
  289. # VelSpec,振动速度频谱
  290. # fmax_vel,最大分析频率
  291. # fTarget,目标频率为转频
  292. Vel_alert_mmsRMS = 4 # 速度总值预警阈值 (mm/s 有效值)
  293. Vel_danger_mmsRMS = 7 # 速度总值报警阈值 (mm/s 有效值)
  294. gE_alert = 3 # 包络总值预警阈值(gE)
  295. gE_danger = 10 # 包络总值报警阈值(gE)
  296. results = {
  297. "BPFO": {"status_codes": []},
  298. "BPFI": {"status_codes": []},
  299. "BSF": {"status_codes": []},
  300. "FTF": {"status_codes": []}
  301. }
  302. # 获取第一个id的特征频率(所有id相同)
  303. id = self.ids[0]
  304. bearing_freq = self.bearing_frequencies.get(id, {})
  305. BPFO = bearing_freq.get("BPFO", 0)
  306. BPFI = bearing_freq.get("BPFI", 0)
  307. BSF = bearing_freq.get("BSF", 0)
  308. FTF = bearing_freq.get("FTF", 0)
  309. for i in range(len(self.ids)):
  310. ShaftSpd = self.fspd[i] * self.speed_ratio
  311. if ShaftSpd == 0:
  312. results["BPFO"]["status_codes"].append(-1)
  313. results["BPFI"]["status_codes"].append(-1)
  314. results["BSF"]["status_codes"].append(-1)
  315. results["FTF"]["status_codes"].append(-1)
  316. continue
  317. fs_acc = self.fs_acc[i]
  318. # fmax_vel =1000
  319. # fmax_vel如果直接取1000 还是会出现目标范围落不到搜寻范围的现象
  320. fmax_vel = max(1000, fs_acc / 2.56)
  321. fRange = 0.05
  322. fmax_gE_10 = 1000
  323. try:
  324. """外圈故障诊断"""
  325. logger.info("外圈")
  326. fbr_BPFO = BPFO
  327. fTarget = fbr_BPFO # 在计算轴承特征频率的函数中已经乘过转速
  328. if self.wind_code == 'WOF091200030':
  329. if fTarget > 100:
  330. fmax_gE_10 = 10000
  331. elif fTarget < 1:
  332. fmax_gE_10 = 10
  333. fmax_vel = min(1000, fs_acc / 2.56)
  334. else:
  335. fmax_gE_10 = 1000
  336. else:
  337. if fTarget > 100:
  338. fmax_gE_10 = 10000
  339. elif fTarget < 10:
  340. fmax_gE_10 = 100
  341. fmax_vel = min(1000, fs_acc / 2.56)
  342. else:
  343. fmax_gE_10 = 1000
  344. numHarmonics = 4
  345. fRangeMode = "Per"
  346. Detection = "RMS"
  347. logger.info('BPFO', BPFO)
  348. logger.info('ShaftSpd', ShaftSpd)
  349. logger.info('speed_ratio', self.speed_ratio)
  350. logger.info('fTarget', fTarget)
  351. logger.info('VelSpec', self.VelSpec[i])
  352. logger.info('gESpec_10', self.gESpec_10[i])
  353. try:
  354. Vel_RunningSpd_HM = self.myDiagnosisLib.FixedFreqFeature(self.VelSpec[i], fmax_vel, fTarget, fRange, \
  355. fRangeMode, Detection, numHarmonics)
  356. except Exception as e:
  357. # logger.info(f"计算 Vel_RunningSpd_HM 时出错: {e}")
  358. Vel_RunningSpd_HM = [0] * (numHarmonics + 1)
  359. logger.info('Vel_RunningSpd_HM\n', Vel_RunningSpd_HM)
  360. # 速度频谱特征
  361. try:
  362. Vel_Bearing_Defect_HM = self.myDiagnosisLib.FixedFreqFeature(
  363. self.VelSpec[i], fmax_vel, fTarget, fRange, fRangeMode, Detection, numHarmonics
  364. )
  365. except Exception as e:
  366. # logger.info(f"计算 Vel_Bearing_Defect_HM 时出错: {e}")
  367. Vel_Bearing_Defect_HM = [0] * (numHarmonics + 1)
  368. logger.info('Vel_Bearing_Defect_HM\n', Vel_Bearing_Defect_HM)
  369. try:
  370. # 包络频谱特征
  371. Detection = "Peak"
  372. gE_Bearing_Defect_HM = self.myDiagnosisLib.FixedFreqFeature(
  373. self.gESpec_10[i], fmax_gE_10, fTarget, fRange, fRangeMode, Detection, numHarmonics
  374. )
  375. except Exception as e:
  376. # logger.info(f"计算 gE_Bearing_Defect_HM 时出错: {e}")
  377. gE_Bearing_Defect_HM = [0] * (numHarmonics + 1)
  378. logger.info('gE_Bearing_Defect_HM\n', gE_Bearing_Defect_HM)
  379. try:
  380. # 诊断外圈故障
  381. BPFOdetection, BPFOseverity = self.myDiagnosisLib.Bearing_Fault_Diag(
  382. gE_Bearing_Defect_HM, Vel_Bearing_Defect_HM, Vel_RunningSpd_HM, gE_alert, gE_danger,
  383. Vel_alert_mmsRMS, Vel_danger_mmsRMS, 'BPFO'
  384. )
  385. except Exception as e:
  386. BPFOdetection = False
  387. BPFOseverity = 0
  388. logger.info("BPFOseverity", BPFOseverity)
  389. if not BPFOdetection:
  390. BPFOStatusCode = 0
  391. elif BPFOseverity < 6:
  392. BPFOStatusCode = 1
  393. else:
  394. BPFOStatusCode = 2
  395. except Exception as e:
  396. BPFOStatusCode = 0
  397. results["BPFO"]["status_codes"].append(BPFOStatusCode)
  398. try:
  399. """内圈故障诊断"""
  400. logger.info("内圈")
  401. fbr_BPFI = BPFI
  402. # fbr_BPFI = ShaftSpd * BPFI
  403. fTarget = fbr_BPFI
  404. if self.wind_code == 'WOF091200030':
  405. if fTarget > 100:
  406. fmax_gE_10 = 10000
  407. elif fTarget < 1:
  408. fmax_gE_10 = 10
  409. fmax_vel = min(1000, fs_acc / 2.56)
  410. else:
  411. fmax_gE_10 = 1000
  412. else:
  413. if fTarget > 100:
  414. fmax_gE_10 = 10000
  415. elif fTarget < 10:
  416. fmax_gE_10 = 100
  417. fmax_vel = min(1000, fs_acc / 2.56)
  418. else:
  419. fmax_gE_10 = 1000
  420. numHarmonics = 4
  421. fRangeMode = "Per"
  422. Detection = "RMS"
  423. logger.info('BPFI', BPFI)
  424. logger.info('ShaftSpd', ShaftSpd)
  425. logger.info('fTarget', fTarget)
  426. try:
  427. Vel_RunningSpd_HM = self.myDiagnosisLib.FixedFreqFeature(self.VelSpec[i], fmax_vel, fTarget, fRange, \
  428. fRangeMode, Detection, numHarmonics)
  429. except Exception as e:
  430. # logger.info(f"计算 Vel_RunningSpd_HM 时出错: {e}")
  431. Vel_RunningSpd_HM = [0] * (numHarmonics + 1)
  432. logger.info('Vel_RunningSpd_HM\n', Vel_RunningSpd_HM)
  433. # 速度频谱特征
  434. try:
  435. Vel_Bearing_Defect_HM = self.myDiagnosisLib.FixedFreqFeature(
  436. self.VelSpec[i], fmax_vel, fTarget, fRange, fRangeMode, Detection, numHarmonics
  437. )
  438. except Exception as e:
  439. # logger.info(f"计算 Vel_Bearing_Defect_HM 时出错: {e}")
  440. Vel_Bearing_Defect_HM = [0] * (numHarmonics + 1)
  441. logger.info('Vel_Bearing_Defect_HM\n', Vel_Bearing_Defect_HM)
  442. # 包络频谱特征
  443. try:
  444. Detection = "Peak"
  445. gE_Bearing_Defect_HM = self.myDiagnosisLib.FixedFreqFeature(
  446. self.gESpec_10[i], fmax_gE_10, fTarget, fRange, fRangeMode, Detection, numHarmonics
  447. )
  448. except Exception as e:
  449. # logger.info(f"计算 gE_Bearing_Defect_HM 时出错: {e}")
  450. gE_Bearing_Defect_HM = [0] * (numHarmonics + 1)
  451. logger.info('gE_Bearing_Defect_HM\n', gE_Bearing_Defect_HM)
  452. try:
  453. # 诊断内圈故障
  454. BPFIdetection, BPFIseverity = self.myDiagnosisLib.Bearing_Fault_Diag(
  455. gE_Bearing_Defect_HM, Vel_Bearing_Defect_HM, Vel_RunningSpd_HM, gE_alert, gE_danger,
  456. Vel_alert_mmsRMS, Vel_danger_mmsRMS, 'BPFI'
  457. )
  458. except Exception as e:
  459. BPFIdetection = False
  460. BPFIseverity = 0
  461. if not BPFIdetection:
  462. BPFIStatusCode = 0
  463. elif BPFIseverity < 6:
  464. BPFIStatusCode = 1
  465. else:
  466. BPFIStatusCode = 2
  467. except Exception as e:
  468. # logger.info(f"处理内圈故障时发生未捕获的异常: {e}")
  469. BPFIStatusCode = 0
  470. results["BPFI"]["status_codes"].append(BPFIStatusCode)
  471. try:
  472. """滚动体故障诊断"""
  473. logger.info("滚动体")
  474. fbr_BSF = BSF
  475. if self.wind_code == 'WOF091200030':
  476. if fTarget > 100:
  477. fmax_gE_10 = 10000
  478. elif fTarget < 1:
  479. fmax_gE_10 = 10
  480. fmax_vel = min(1000, fs_acc / 2.56)
  481. else:
  482. fmax_gE_10 = 1000
  483. else:
  484. if fTarget > 100:
  485. fmax_gE_10 = 10000
  486. elif fTarget < 10:
  487. fmax_gE_10 = 100
  488. fmax_vel = min(1000, fs_acc / 2.56)
  489. else:
  490. fmax_gE_10 = 1000
  491. numHarmonics = 4
  492. fTarget = fbr_BSF
  493. fRangeMode = "Per"
  494. Detection = "RMS"
  495. logger.info('BSF', BSF)
  496. logger.info('ShaftSpd', ShaftSpd)
  497. logger.info('fTarget', fTarget)
  498. try:
  499. Vel_RunningSpd_HM = self.myDiagnosisLib.FixedFreqFeature(self.VelSpec[i], fmax_vel, fTarget, fRange, \
  500. fRangeMode, Detection, numHarmonics)
  501. except Exception as e:
  502. # logger.info(f"计算 Vel_RunningSpd_HM 时出错: {e}")
  503. Vel_RunningSpd_HM = [0] * (numHarmonics + 1)
  504. logger.info('Vel_RunningSpd_HM\n', Vel_RunningSpd_HM)
  505. try:
  506. # 速度频谱特征
  507. Vel_Bearing_Defect_HM = self.myDiagnosisLib.FixedFreqFeature(
  508. self.VelSpec[i], fmax_vel, fTarget, fRange, fRangeMode, Detection, numHarmonics
  509. )
  510. except Exception as e:
  511. # logger.info(f"计算 Vel_Bearing_Defect_HM 时出错: {e}")
  512. Vel_Bearing_Defect_HM = [0] * (numHarmonics + 1)
  513. logger.info('Vel_Bearing_Defect_HM\n', Vel_Bearing_Defect_HM)
  514. try:
  515. # 包络频谱特征S
  516. Detection = "Peak"
  517. gE_Bearing_Defect_HM = self.myDiagnosisLib.FixedFreqFeature(
  518. self.gESpec_10[i], fmax_gE_10, fTarget, fRange, fRangeMode, Detection, numHarmonics
  519. )
  520. except Exception as e:
  521. # logger.info(f"计算 gE_Bearing_Defect_HM 时出错: {e}")
  522. gE_Bearing_Defect_HM = [0] * (numHarmonics + 1)
  523. logger.info('gE_Bearing_Defect_HM\n', gE_Bearing_Defect_HM)
  524. try:
  525. # 诊断滚动体故障
  526. BSFdetection, BSFseverity = self.myDiagnosisLib.Bearing_Fault_Diag(
  527. gE_Bearing_Defect_HM, Vel_Bearing_Defect_HM, Vel_RunningSpd_HM, gE_alert, gE_danger,
  528. Vel_alert_mmsRMS, Vel_danger_mmsRMS, 'BSF'
  529. )
  530. except Exception as e:
  531. BSFdetection = False
  532. BSFseverity = 0
  533. if not BSFdetection:
  534. BSFStatusCode = 0
  535. elif BSFseverity < 6:
  536. BSFStatusCode = 1
  537. else:
  538. BSFStatusCode = 2
  539. except Exception as e:
  540. # logger.info(f"处理滚动体故障时发生未捕获的异常: {e}")
  541. BSFStatusCode = 0
  542. results["BSF"]["status_codes"].append(BSFStatusCode)
  543. try:
  544. """保持架故障诊断"""
  545. logger.info("保持架")
  546. fbr_FTF = FTF
  547. fTarget = fbr_FTF
  548. if self.wind_code == 'WOF091200030':
  549. if fTarget > 100:
  550. fmax_gE_10 = 10000
  551. elif fTarget < 1:
  552. fmax_gE_10 = 10
  553. fmax_vel = min(1000, fs_acc / 2.56)
  554. else:
  555. fmax_gE_10 = 1000
  556. else:
  557. if fTarget > 100:
  558. fmax_gE_10 = 10000
  559. # elif fTarget <1:
  560. # fmax_gE_10 =0.001
  561. # fmax_vel=min(1000,fs_acc/2.56)
  562. elif fTarget < 10:
  563. fmax_gE_10 = 10
  564. fmax_vel = min(1000, fs_acc / 2.56)
  565. else:
  566. fmax_gE_10 = 1000
  567. numHarmonics = 4
  568. fRangeMode = "Per"
  569. Detection = "RMS"
  570. logger.info('FTF', FTF)
  571. logger.info('ShaftSpd', ShaftSpd)
  572. logger.info('fTarget', fTarget)
  573. try:
  574. Vel_RunningSpd_HM = self.myDiagnosisLib.FixedFreqFeature(self.VelSpec[i], fmax_vel, fTarget, fRange, \
  575. fRangeMode, Detection, numHarmonics)
  576. except Exception as e:
  577. # logger.info(f"计算 Vel_RunningSpd_HM 时出错: {e}")
  578. Vel_RunningSpd_HM = [0] * (numHarmonics + 1)
  579. logger.info('Vel_RunningSpd_HM\n', Vel_RunningSpd_HM)
  580. try:
  581. # 速度频谱特征
  582. Vel_Bearing_Defect_HM = self.myDiagnosisLib.FixedFreqFeature(
  583. self.VelSpec[i], fmax_vel, fTarget, fRange, fRangeMode, Detection, numHarmonics
  584. )
  585. except Exception as e:
  586. # logger.info(f"计算 Vel_Bearing_Defect_HM 时出错: {e}")
  587. Vel_Bearing_Defect_HM = [0] * (numHarmonics + 1)
  588. logger.info('Vel_Bearing_Defect_HM\n', Vel_Bearing_Defect_HM)
  589. try:
  590. # 包络频谱特征
  591. Detection = "Peak"
  592. gE_Bearing_Defect_HM = self.myDiagnosisLib.FixedFreqFeature(
  593. self.gESpec_10[i], fmax_gE_10, fTarget, fRange, fRangeMode, Detection, numHarmonics
  594. )
  595. except Exception as e:
  596. # logger.info(f"计算 gE_Bearing_Defect_HM 时出错: {e}")
  597. gE_Bearing_Defect_HM = [0] * (numHarmonics + 1)
  598. logger.info('gE_Bearing_Defect_HM\n', gE_Bearing_Defect_HM)
  599. try:
  600. # 诊断保持架故障
  601. FTFdetection, FTFseverity = self.myDiagnosisLib.Bearing_Fault_Diag(
  602. gE_Bearing_Defect_HM, Vel_Bearing_Defect_HM, Vel_RunningSpd_HM, gE_alert, gE_danger,
  603. Vel_alert_mmsRMS, Vel_danger_mmsRMS, 'FTF'
  604. )
  605. except Exception as e:
  606. FTFdetection = False
  607. FTFseverity = 0
  608. if not FTFdetection:
  609. FTFStatusCode = 0
  610. elif FTFseverity < 6:
  611. FTFStatusCode = 1
  612. else:
  613. FTFStatusCode = 2
  614. except Exception as e:
  615. # logger.info(f"处理保持架故障时发生未捕获的异常: {e}")
  616. FTFStatusCode = 0
  617. results["FTF"]["status_codes"].append(FTFStatusCode)
  618. # 计算统计信息
  619. status_counts = {"count_0": 0, "count_1": 0, "count_2": 0}
  620. for fault_type in results:
  621. status_codes = results[fault_type]["status_codes"]
  622. results[fault_type]["max_status"] = max(status_codes)
  623. # 累加状态计数
  624. status_counts["count_0"] += status_codes.count(0)
  625. status_counts["count_1"] += status_codes.count(1)
  626. status_counts["count_2"] += status_codes.count(2)
  627. return {
  628. "type": "Bearing",
  629. "results": results,
  630. "statistics": status_counts
  631. }
  632. def Gear_diag(self):
  633. """齿轮诊断"""
  634. logger.info('齿轮诊断')
  635. mesure_point_name = self.mesure_point_names[0].lower()
  636. if 'gearbox' not in mesure_point_name:
  637. logger.info("Can not perform gearbox diagnosis")
  638. raise ValueError("Can not perform gearbox diagnosis")
  639. results = {
  640. "wear": {"status_codes": []},
  641. "crack": {"status_codes": []}
  642. }
  643. id = self.ids[0]
  644. numTeeth = int(self.teeth_count.get(id, 0))
  645. logger.info(numTeeth)
  646. for i in range(len(self.ids)):
  647. ShaftSpd = self.fspd[i] * self.speed_ratio
  648. if ShaftSpd == 0:
  649. results["wear"]["status_codes"].append(-1)
  650. results["crack"]["status_codes"].append(-1)
  651. logger.info('speed_ratio', self.speed_ratio)
  652. logger.info('ShaftSpd', ShaftSpd)
  653. try:
  654. GMF = ShaftSpd * numTeeth / 60
  655. fTarget = GMF
  656. logger.info('fTarget', fTarget)
  657. # numHarmonics = 2
  658. numHarmonics = 2
  659. fRange = 0.05
  660. fmax_gE_10 = 1000
  661. fs_acc = self.fs_acc[i]
  662. fmax_vel = max(1000, fs_acc / 2.56)
  663. if fTarget > 100:
  664. fmax_gE_10 = 10000
  665. elif fTarget < 0.1:
  666. fmax_gE_10 = 10
  667. elif fTarget < 1:
  668. fmax_gE_10 = 100
  669. fmax_vel = min(1000, fs_acc / 2.56)
  670. else:
  671. fmax_gE_10 = 1000
  672. fmax_acc = fs_acc / 2.56
  673. try:
  674. Vel_GMF_HM = self.myDiagnosisLib.FixedFreqFeature(
  675. self.VelSpec[i], fmax_vel, fTarget, fRange, "Per", "RMS", numHarmonics
  676. )
  677. except Exception as e:
  678. # logger.info(f"计算 Vel_GMF_HM 时出错: {e}")
  679. Vel_GMF_HM = [0] * (numHarmonics + 1)
  680. logger.info('Vel_GMF_HM', Vel_GMF_HM)
  681. try:
  682. Acc_GMF_HM = self.myDiagnosisLib.FixedFreqFeature(
  683. self.AccSpec[i], fmax_acc, fTarget, fRange, "Per", "Peak", numHarmonics
  684. )
  685. except Exception as e:
  686. # logger.info(f"计算 Acc_GMF_HM 时出错: {e}")
  687. Acc_GMF_HM = [0] * (numHarmonics + 1)
  688. logger.info('Acc_GMF_HM', Acc_GMF_HM)
  689. try:
  690. gE_GMF_HM = self.myDiagnosisLib.FixedFreqFeature(
  691. self.gESpec_10[i], fmax_gE_10, fTarget, fRange, "Per", "Peak", numHarmonics
  692. )
  693. except Exception as e:
  694. # logger.info(f"计算 gE_GMF_HM 时出错: {e}")
  695. gE_GMF_HM = [0] * (numHarmonics + 1)
  696. logger.info('gE_GMF_HM', gE_GMF_HM)
  697. fTarget = ShaftSpd / 60
  698. logger.info('fTarget', fTarget)
  699. if fTarget > 100:
  700. fmax_gE_10 = 10000
  701. elif fTarget < 0.1:
  702. fmax_gE_10 = 10
  703. elif fTarget < 1:
  704. fmax_gE_10 = 100
  705. fmax_vel = min(1000, fs_acc / 2.56)
  706. else:
  707. fmax_gE_10 = 1000
  708. numHarmonics = 4
  709. try:
  710. gE_GTIF_HM = self.myDiagnosisLib.FixedFreqFeature(
  711. self.gESpec_10[i], fmax_gE_10, fTarget, fRange, "Per", "Peak", numHarmonics
  712. )
  713. except Exception as e:
  714. # logger.info(f"计算 gE_GTIF_HM 时出错: {e}")
  715. gE_GTIF_HM = [0] * (numHarmonics + 1)
  716. logger.info('gE_GTIF_HM', gE_GTIF_HM)
  717. Acc_GMF_alert_gPk = 0.3 # 齿轮缺陷加速度预警阈值 (g 峰值)
  718. Acc_GMF_danger_gPk = 0.5 # 齿轮缺陷加速度报警阈值 (g 峰值)
  719. Vel_GMF_alert_mmsRMS = 4.0 # 速度总值预警阈值 (mm/s 有效值)
  720. Vel_GMF_danger_mmsRMS = 7.0 # 速度总值报警阈值 (mm/s 有效值)
  721. gE_GMF_alert_gE = 3.0 # 齿轮磨损缺陷加速度包络预警阈值 (gE 峰值)
  722. gE_GMF_danger_gE = 10.0 # 齿轮磨损缺陷加速度包络报警阈值 (gE 峰值)
  723. gE_GTIF_alert_gE = 3.0 # 齿轮断齿缺陷加速度包络预警阈值 (gE 峰值)
  724. gE_GTIF_danger_gE = 10.0 # 齿轮断齿缺陷加速度包络报警阈值 (gE 峰值)
  725. try:
  726. # 诊断齿轮故障
  727. (GearToothWearDetection, GearToothWearSev, GearToothCrackBrokenDetection, GearToothCrackBrokenSev) = \
  728. self.myDiagnosisLib.Gear_Fault_Diag(Acc_GMF_HM, Vel_GMF_HM, gE_GMF_HM, gE_GTIF_HM,
  729. Acc_GMF_alert_gPk, \
  730. Acc_GMF_danger_gPk, Vel_GMF_alert_mmsRMS,
  731. Vel_GMF_danger_mmsRMS, gE_GMF_alert_gE,
  732. gE_GMF_danger_gE, \
  733. gE_GTIF_alert_gE, gE_GTIF_danger_gE)
  734. except Exception as e:
  735. GearToothWearDetection = False
  736. GearToothCrackBrokenDetection = False
  737. GearToothWearSev = 0
  738. GearToothCrackBrokenSev = 0
  739. logger.info('齿轮磨损', GearToothWearSev, '齿轮断齿', GearToothCrackBrokenSev)
  740. # 处理磨损状态码
  741. if not GearToothWearDetection:
  742. wear_status = 0
  743. elif GearToothWearSev < 6:
  744. wear_status = 1
  745. else:
  746. wear_status = 2
  747. # 处理裂纹状态码
  748. if not GearToothCrackBrokenDetection:
  749. crack_status = 0
  750. elif GearToothCrackBrokenSev < 6:
  751. crack_status = 1
  752. else:
  753. crack_status = 2
  754. except Exception as e:
  755. wear_status = 0
  756. crack_status = 0
  757. results["wear"]["status_codes"].append(wear_status)
  758. results["crack"]["status_codes"].append(crack_status)
  759. # 计算统计信息
  760. status_counts = {"count_0": 0, "count_1": 0, "count_2": 0}
  761. for fault_type in results:
  762. status_codes = results[fault_type]["status_codes"]
  763. results[fault_type]["max_status"] = max(status_codes)
  764. # 累加状态计数
  765. status_counts["count_0"] += status_codes.count(0)
  766. status_counts["count_1"] += status_codes.count(1)
  767. status_counts["count_2"] += status_codes.count(2)
  768. return {
  769. "type": "Gear",
  770. "results": results,
  771. "statistics": status_counts
  772. }
  773. def Characteristic_Frequency(self):
  774. """提取轴承、齿轮等参数"""
  775. # 前端给的ids所对应的轴承参数、齿轮参数是一致的 计算一次即可
  776. if not self.bearing_frequencies:
  777. id = self.ids[0] # 取第一个id计算
  778. mesure_point_name = self.mesure_point_names[0]
  779. rpm = self.fspd[0] * self.speed_ratio # 应用转速传动比
  780. # 1、从测点名称中提取部件名称(计算特征频率的部件)
  781. str1 = mesure_point_name
  782. logger.info(str1)
  783. # 2、连接233的数据库'energy_show',从表'wind_engine_group'查找风机编号'engine_code'对应的机型编号'mill_type_code'
  784. engine_code = self.engine_code
  785. logger.info(engine_code)
  786. Engine = get_engine(dataBase.PLATFORM_DB)
  787. # Engine = create_engine('mysql+pymysql://admin:admin123456@106.120.102.238:16306/energy_show')
  788. df_sql2 = f"SELECT * FROM wind_engine_group WHERE engine_code = '{engine_code}'"
  789. df2 = pd.read_sql(df_sql2, Engine)
  790. mill_type_code = df2['mill_type_code'].iloc[0]
  791. logger.info(mill_type_code)
  792. # 3、从相关的表中通过机型编号'mill_type_code'或者齿轮箱编号gearbox_code查找部件'brand'、'model'的参数信息
  793. # unit_bearings主轴承参数表 关键词"main_bearing"
  794. if 'main_bearing' in str1:
  795. logger.info("main_bearing")
  796. # df_sql3 = f"SELECT * FROM {'unit_bearings'} where mill_type_code = {'mill_type_code'} "
  797. df_sql3 = f"SELECT * FROM unit_bearings WHERE mill_type_code = '{mill_type_code}' "
  798. df3 = pd.read_sql(df_sql3, Engine)
  799. if df3.empty:
  800. logger.info("警告: 没有找到有效的机型信息")
  801. if 'front' in str1:
  802. brand = 'front_bearing' + '_brand'
  803. model = 'front_bearing' + '_model'
  804. front_has_value = not pd.isna(df3[brand].iloc[0]) and not pd.isna(df3[model].iloc[0])
  805. if not front_has_value:
  806. logger.info("警告: 没有找到有效的品牌信息")
  807. elif 'rear' in str1:
  808. brand = 'rear_bearing' + '_brand'
  809. model = 'rear_bearing' + '_model'
  810. end_has_value = not pd.isna(df3[brand].iloc[0]) and not pd.isna(df3[model].iloc[0])
  811. if not end_has_value:
  812. logger.info("警告: 没有找到有效的品牌信息")
  813. else:
  814. # 当没有指定 front 或 end 时,自动选择有值的轴承信息
  815. front_brand_col = 'front_bearing_brand'
  816. front_model_col = 'front_bearing_model'
  817. rear_brand_col = 'rear_bearing_brand'
  818. rear_model_col = 'rear_bearing_model'
  819. # 检查 front_bearing 是否有值
  820. front_has_value = not pd.isna(df3[front_brand_col].iloc[0]) and not pd.isna(
  821. df3[front_model_col].iloc[0])
  822. # 检查 end_bearing 是否有值
  823. end_has_value = not pd.isna(df3[rear_brand_col].iloc[0]) and not pd.isna(
  824. df3[rear_model_col].iloc[0])
  825. # 根据检查结果选择合适的列
  826. if front_has_value and end_has_value:
  827. # 如果两者都有值,默认选择 front
  828. brand = front_brand_col
  829. model = front_model_col
  830. elif front_has_value:
  831. brand = front_brand_col
  832. model = front_model_col
  833. elif end_has_value:
  834. brand = rear_brand_col
  835. model = rear_model_col
  836. else:
  837. # 如果两者都没有有效值,设置默认值或抛出异常
  838. logger.info("警告: 没有找到有效的轴承信息")
  839. brand = front_brand_col # 默认使用 front
  840. model = front_model_col # 默认使用 front
  841. logger.info(brand)
  842. _brand = df3[brand].iloc[0]
  843. _model = df3[model].iloc[0]
  844. logger.info(_brand)
  845. logger.info(_model)
  846. # unit_dynamo 发电机参数表 关键词generator stator
  847. elif 'generator' in str1 or 'stator' in str1:
  848. logger.info("generator or 'stator'")
  849. # df_sql3 = f"SELECT * FROM {'unit_dynamo'} where mill_type_code = {'mill_type_code'} "
  850. df_sql3 = f"SELECT * FROM unit_dynamo WHERE mill_type_code = '{mill_type_code}' "
  851. df3 = pd.read_sql(df_sql3, Engine)
  852. if 'non' in str1:
  853. brand = 'non_drive_end_bearing' + '_brand'
  854. model = 'non_drive_end_bearing' + '_model'
  855. else:
  856. brand = 'drive_end_bearing' + '_brand'
  857. model = 'drive_end_bearing' + '_model'
  858. logger.info(brand)
  859. _brand = df3[brand].iloc[0]
  860. _model = df3[model].iloc[0]
  861. logger.info(_brand)
  862. logger.info(_model)
  863. # 齿轮箱区分行星轮/平行轮 和 轴承两个表
  864. elif 'gearbox' in str1:
  865. logger.info("gearbox")
  866. # 根据mill_type_code从unit_gearbox表中获得gearbox_code
  867. df_sql3 = f"SELECT * FROM unit_gearbox WHERE mill_type_code = '{mill_type_code}' "
  868. df3 = pd.read_sql(df_sql3, Engine)
  869. gearbox_code = df3['code'].iloc[0]
  870. logger.info(gearbox_code)
  871. # 如果是行星轮/平行轮 则从unit_gearbox_structure 表中取数据
  872. if 'planet' in str1 or 'sun' in str1:
  873. logger.info("'planet' or 'sun' ")
  874. gearbox_structure = 1 if 'planet' in str1 else 2
  875. planetary_gear_grade = 1
  876. if 'first' in str1:
  877. planetary_gear_grade = 1
  878. elif 'second' in str1:
  879. planetary_gear_grade = 2
  880. elif 'third' in str1:
  881. planetary_gear_grade = 3
  882. # df_sql33 = f"SELECT * FROM unit_gearbox_structure WHERE gearbox_code = '{gearbox_code}' "
  883. df_sql33 = f"""
  884. SELECT bearing_brand, bearing_model,gear_ring_teeth_count
  885. FROM unit_gearbox_structure
  886. WHERE gearbox_code = '{gearbox_code}'
  887. AND gearbox_structure = '{gearbox_structure}'
  888. AND planetary_gear_grade = '{planetary_gear_grade}'
  889. """
  890. df33 = pd.read_sql(df_sql33, Engine)
  891. if df33.empty:
  892. logger.info("unit_gearbox_structure没有该测点的参数")
  893. else:
  894. brand = 'bearing' + '_brand'
  895. model = 'bearing' + '_model'
  896. teeth_count = df33['gear_ring_teeth_count'].iloc[0]
  897. logger.info('teeth_count', teeth_count)
  898. logger.info(brand)
  899. _brand = df33[brand].iloc[0]
  900. _model = df33[model].iloc[0]
  901. has_value = not pd.isna(df33[brand].iloc[0]) and not pd.isna(df33[model].iloc[0])
  902. if has_value:
  903. logger.info(_brand)
  904. logger.info(_model)
  905. else:
  906. logger.info("警告: 没有找到有效的轴承信息")
  907. # 如果是齿轮箱轴承 则从unit_gearbox_bearings 表中取数据
  908. elif 'shaft' in str1 or 'input' in str1:
  909. logger.info("'shaft'or'input'")
  910. # 高速轴 低速中间轴 取bearing_rs/gs均可
  911. parallel_wheel_grade = 1
  912. if 'low_speed' in str1:
  913. parallel_wheel_grade = 1
  914. elif 'low_speed_intermediate' in str1:
  915. parallel_wheel_grade = 2
  916. elif 'high_speed' in str1:
  917. parallel_wheel_grade = 3
  918. df_sql33 = f"""
  919. SELECT bearing_rs_brand, bearing_rs_model, bearing_gs_brand, bearing_gs_model,gear_ring_teeth_count
  920. FROM unit_gearbox_bearings
  921. WHERE gearbox_code = '{gearbox_code}'
  922. AND parallel_wheel_grade = '{parallel_wheel_grade}'
  923. """
  924. df33 = pd.read_sql(df_sql33, Engine)
  925. if not df33.empty:
  926. if 'high_speed' in str1 or 'low_speed_intermediate' in str1:
  927. rs_brand = 'bearing_rs' + '_brand'
  928. rs_model = 'bearing_rs' + '_model'
  929. gs_brand = 'bearing_gs' + '_brand'
  930. gs_model = 'bearing_gs' + '_model'
  931. rs_has_value = not pd.isna(df33[rs_brand].iloc[0]) and not pd.isna(df33[rs_model].iloc[0])
  932. gs_has_value = not pd.isna(df33[gs_brand].iloc[0]) and not pd.isna(df33[gs_model].iloc[0])
  933. if rs_has_value and gs_has_value:
  934. brand = rs_brand
  935. model = rs_model
  936. elif rs_has_value:
  937. brand = rs_brand
  938. model = rs_model
  939. elif gs_has_value:
  940. brand = gs_brand
  941. model = gs_model
  942. else:
  943. logger.info("警告: 没有找到有效的品牌信息")
  944. brand = rs_brand
  945. model = rs_model
  946. # 低速轴 取bearing_model
  947. elif 'low_speed' in str1:
  948. brand = 'bearing' + '_brand'
  949. model = 'bearing' + '_model'
  950. else:
  951. logger.info("警告: 没有找到有效的轴承信息")
  952. if not df33.empty:
  953. if 'high_speed' in str1:
  954. teeth_count = df33['gear_ring_teeth_count'].iloc[0]
  955. logger.info('teeth_count', teeth_count)
  956. logger.info(brand)
  957. _brand = df33[brand].iloc[0]
  958. _model = df33[model].iloc[0]
  959. logger.info(_brand)
  960. logger.info(_model)
  961. # 4、从表'unit_dict_brand_model'中通过'_brand'、'_model'查找部件的参数信息
  962. df_sql4 = f"SELECT * FROM unit_dict_brand_model where manufacture = %s AND model_number = %s"
  963. params = [(_brand, _model)]
  964. df4 = pd.read_sql(df_sql4, Engine, params=params)
  965. n_rolls = df4['rolls_number'].iloc[0]
  966. d_rolls = df4['rolls_diameter'].iloc[0]
  967. D_diameter = df4['circle_diameter'].iloc[0]
  968. theta_deg = df4['theta_deg'].iloc[0]
  969. # 计算特征频率
  970. bearing_freq = self.calculate_bearing_frequencies(n_rolls, d_rolls, D_diameter, theta_deg, rpm)
  971. logger.info(bearing_freq)
  972. # 将结果赋给所有id
  973. for id in self.ids:
  974. self.bearing_frequencies[id] = bearing_freq
  975. logger.info('aaaa')
  976. if 'gearbox' in str1:
  977. self.teeth_count[id] = teeth_count
  978. def calculate_bearing_frequencies(self, n, d, D, theta_deg, rpm):
  979. """
  980. 计算轴承各部件特征频率
  981. 参数:
  982. n (int): 滚动体数量
  983. d (float): 滚动体直径(单位:mm)
  984. D (float): 轴承节圆直径(滚动体中心圆直径,单位:mm)
  985. theta_deg (float): 接触角(单位:度)
  986. rpm (float): 转速(转/分钟)
  987. 返回:
  988. dict: 包含各特征频率的字典(单位:Hz)
  989. """
  990. # 转换角度为弧度
  991. theta = math.radians(theta_deg)
  992. # 转换直径单位为米(保持单位一致性,实际计算中比值抵消单位影响)
  993. # 注意:由于公式中使用的是比值,单位可以保持mm不需要转换
  994. ratio = d / D
  995. # 基础频率计算(转/秒)
  996. # f_r = rpm
  997. f_r = rpm / 60.0
  998. # 计算各特征频率
  999. BPFI = (n / 2) * (1 + ratio * math.cos(theta)) * f_r # 内圈故障频率
  1000. BPFO = (n / 2) * (1 - ratio * math.cos(theta)) * f_r # 外圈故障频率
  1001. BSF = (D / (2 * d)) * (1 - (ratio ** 2) * (math.cos(theta) ** 2)) * f_r # 滚动体故障频率
  1002. FTF = 0.5 * (1 - ratio * math.cos(theta)) * f_r # 保持架故障频率
  1003. return {
  1004. "BPFI": round(BPFI, 2),
  1005. "BPFO": round(BPFO, 2),
  1006. "BSF": round(BSF, 2),
  1007. "FTF": round(FTF, 2),
  1008. }
  1009. def calculate_speed_ratio(self):
  1010. """
  1011. 根据风场编号和测点名称计算转速传动比
  1012. """
  1013. # 默认传动比为1
  1014. self.speed_ratio = 1.0
  1015. # WOF046400029风场 七台河需要特殊处理
  1016. if self.wind_code == "WOF046400029":
  1017. # 获取第一个测点名称
  1018. mesure_point_name = self.mesure_point_names[0]
  1019. if "gearbox" in mesure_point_name:
  1020. if "high_speed" in mesure_point_name:
  1021. # 高速轴输出端
  1022. self.speed_ratio = 1
  1023. elif "first" in mesure_point_name:
  1024. # 一级行星级
  1025. self.speed_ratio = 1 / (5.3 * 5.5 * 3.8)
  1026. elif "second" in mesure_point_name:
  1027. # 二级行星级
  1028. self.speed_ratio = 1 / (5.5 * 3.8)
  1029. if "generator" in mesure_point_name:
  1030. self.speed_ratio = 1
  1031. else:
  1032. # 非齿轮箱测点
  1033. self.speed_ratio = 1 / (5.3 * 5.5 * 3.8)