presets.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. """合成测试输入,与扫描报告的自动识别事实独立。"""
  2. from copy import deepcopy
  3. from datetime import datetime, timedelta
  4. from algorithms.main_fan.models import ScreeningInput
  5. PRESETS = (
  6. {'id':'normal','name':'主备运行正常','description':'参数一致,切换6分钟,风量变化5%。','expected':'NORMAL','tag':'规则样例'},
  7. {'id':'warning','name':'风量轻度偏差','description':'参数一致,切换6分钟,风量变化12%。','expected':'WARNING','tag':'规则样例'},
  8. {'id':'abnormal','name':'风量明显偏差','description':'参数一致,切换6分钟,风量变化20%。','expected':'ABNORMAL','tag':'规则样例'},
  9. {'id':'insufficient','name':'缺少切换记录','description':'保留双机报告参数,未提供有效切换时序。','expected':'UNDETERMINED','tag':'规则样例'},
  10. {'id':'documents','name':'PDF资料研判','description':'选择原始PDF或上传资料,配合主备开停与风量曲线研判。','expected':None,'tag':'原件识别'},
  11. {'id':'gateway','name':'网关取数联调','description':'从当前已配置网关取得资料,运行真实取数与研判流程。','expected':None,'tag':'网关资料'},
  12. )
  13. def preset(identifier):
  14. try:
  15. return deepcopy(next(p for p in PRESETS if p['id']==identifier))
  16. except StopIteration:
  17. raise ValueError('测试样例不存在') from None
  18. def main_fan_input(identifier):
  19. preset(identifier)
  20. at = datetime.fromisoformat('2026-10-14T10:00:00+08:00')
  21. common = {'mine_code':'mock-zy','mine_name':'陕西众源煤业集团有限公司'}
  22. evidence = {'source':'test-lab://main-fan/'+identifier,'method':'synthetic','label':'智能体测试样例','excerpt':'合成数据,用于验证主备风机判识流程'}
  23. ids = ['mock-report-fan-1','mock-report-fan-2']
  24. data = {**common,'fan_id':ids[0],'fan_name':'1号通风机','fan_pair':ids,
  25. 'evaluation_time':'2026-10-14T12:00:00+08:00','use_gateway':identifier=='gateway',
  26. 'document_cache_policy':'auto','paired_assessment':True,'reports':[],
  27. 'devices':[{'device_code':key,'name':f'{i+1}号通风机',**common,'evidence':evidence} for i,key in enumerate(ids)],
  28. 'fan_state_records':[],'operating_series':[]}
  29. if identifier=='gateway':
  30. data['devices']=[]
  31. if identifier not in {'documents','gateway'}:
  32. for i in range(2):
  33. points = []
  34. for frequency in (30,40,50):
  35. factor = frequency/30
  36. for j in range(7):
  37. flow, pressure, power = (42+j*5)*factor, (920-j*95)*factor**2, (55-j)*factor**3
  38. if i:
  39. pressure *= .99
  40. power *= .995
  41. points.append({'frequency_hz':frequency,'flow_m3_s':flow,'static_pressure_pa':pressure,
  42. 'shaft_power_kw':power,'reported_efficiency_pct':flow*pressure/(10*power),
  43. 'label':f'测点{j+1}','evidence':evidence})
  44. data['reports'].append({**common,'report_id':f'TEST-LAB-{i+1}','fan_name':f'{i+1}号通风机',
  45. 'serial_number':f'TEST-{i+1}','model':'FBCDZ-№24','motor_model':'YBF2355L1-8',
  46. 'rated_power_raw':'2×185 kW','rated_speed_rpm':740,'impeller_diameter_m':2.4,
  47. 'blade_angle_deg':35,'inspected_on':'2026-10-01','points':points,'evidence':evidence})
  48. if identifier not in {'insufficient','gateway'}:
  49. after = {'warning':.88,'abnormal':.8}.get(identifier,.95)*3800
  50. values = [[],[]]
  51. for minute in range(-40,61):
  52. time = at+timedelta(minutes=minute)
  53. for i,fan_id in enumerate(ids):
  54. running = minute<0 if i==0 else minute>=6
  55. data['fan_state_records'].append({**common,'fan_id':fan_id,'observed_at':time.isoformat(),
  56. 'state':'running' if running else 'stopped','complete_fan_state':True,'evidence':evidence})
  57. values[i].append({'observed_at':time.isoformat(),'value':(3800 if i==0 else after) if running else 0})
  58. data['operating_series']=[{**common,'fan_id':fan_id,'metric':'flow','unit':'m3/min',
  59. 'sensor_id':f'test-flow-{i+1}','mapping_confirmed':True,'samples':values[i],'evidence':evidence} for i,fan_id in enumerate(ids)]
  60. # 预先验证样例,禁止无效或隐含人工转录的输入进入工作台。
  61. core={k:v for k,v in data.items() if k in ScreeningInput.model_fields}
  62. ScreeningInput.model_validate(core)
  63. return data