data_checker.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. from utils.s7data import S7data
  2. from utils.logger import Logger
  3. import requests, time, threading, warnings
  4. class Checker:
  5. def __init__(self, data_5: S7data, data_6: S7data, logger: Logger):
  6. self.data_5 = data_5
  7. self.data_6 = data_6
  8. self.logger = logger
  9. self.already = set()
  10. self.policy_5 = {
  11. # 信号: [无响应报警间隔, 信号描述, 信号名称, 处理方法]
  12. '定尺看门狗1': [120, '5#机1-4流定尺数据', '定尺信号', '立刻排查通信'],
  13. '定尺看门狗2': [120, '5#机5-8流定尺数据', '定尺信号', '立刻排查通信'],
  14. '推钢机激光': [1800, '5#机组坯、装运等除直轧外所有数据', '推钢机信号', '排查停机、plc内信号响应'],
  15. ('天车A1位置', '天车A2位置', '天车A3位置'): [600, '所有天车吊运钢坯数据', '天车位置信号', '立刻排查plc内信号,小概率是停机导致'],
  16. '车位1视觉看门狗': [120, '5#机车位1到站离站信号、车厢数据', '车位1信号', '立刻排查通信、识别软件是否启动'],
  17. '车位2视觉看门狗': [120, '5#机车位2到站离站信号、车厢数据', '车位2信号', '立刻排查通信、识别软件是否启动'],
  18. '车位3视觉看门狗': [120, '5#机车位3到站离站信号、车厢数据', '车位3信号', '立刻排查通信、识别软件是否启动'],
  19. '车位4视觉看门狗': [120, '5#机车位4到站离站信号、车厢数据', '车位4信号', '立刻排查通信、识别软件是否启动'],
  20. '车位1车牌看门狗': [120, '5#机车位1车牌识别', '车位1车牌识别', '立刻排查通信、识别软件是否启动'],
  21. '车位2车牌看门狗': [120, '6#机车位2车牌识别', '车位2车牌识别', '立刻排查通信、识别软件是否启动'],
  22. '车位3车牌看门狗': [120, '6#机车位3车牌识别', '车位3车牌识别', '立刻排查通信、识别软件是否启动'],
  23. '车位4车牌看门狗': [120, '6#机车位4车牌识别', '车位4车牌识别', '立刻排查通信、识别软件是否启动'],
  24. ('L1切割信号[1]', 'L2切割信号[1]', 'L3切割信号[1]', 'L4切割信号[1]'): [1800, '5#机1-4流切割数据', '液压剪信号', '立刻排查停机/通信异常'],
  25. ('L5切割信号[1]', 'L6切割信号[1]', 'L7切割信号[1]', 'L8切割信号[1]'): [1800, '5#机5-8流切割数据', '液压剪信号', '立刻排查停机/通信异常']
  26. }
  27. self.policy_6 = {
  28. '定尺看门狗1': [120, '6#机1-4流定尺数据', '定尺信号', '立刻排查通信'],
  29. '定尺看门狗2': [120, '6#机5-8流定尺数据', '定尺信号', '立刻排查通信'],
  30. '推钢机激光': [1800, '6#机钢坯基础信息、组坯等所有数据', '推钢机信号', '排查停机、plc内信号响应'],
  31. ('L1切割信号[1]', 'L2切割信号[1]', 'L3切割信号[1]', 'L4切割信号[1]'): [1800, '6#机1-4流切割数据', '液压剪信号', '立刻排查停机/通信异常'],
  32. ('L5切割信号[1]', 'L6切割信号[1]', 'L7切割信号[1]', 'L8切割信号[1]'): [1800, '6#机5-8流切割数据', '液压剪信号', '立刻排查停机/通信异常']
  33. }
  34. self.time_5 = {}
  35. self.time_6 = {}
  36. self.value_5 = {}
  37. self.value_6 = {}
  38. now = time.time()
  39. for i in self.policy_5.keys():
  40. self.time_5[i] = now
  41. self.value_5[i] = 0
  42. for i in self.policy_6.keys():
  43. self.time_6[i] = now
  44. self.value_6[i] = 0
  45. self.threading_sig = True
  46. def push(self, name, ccmNo):
  47. url = 'https://oapi.dingtalk.com/robot/send?access_token=60fbad9923c55730485ead3270621fd0a03fdc28d6a8e78a85a4ce4d0ee727dd'
  48. tmp = {}
  49. tmp['msgtype'] = 'markdown'
  50. tmp['markdown'] = {}
  51. tmp['markdown']['title'] = '数据异常警告'
  52. tmp['markdown']['text'] = f'''#### 警告:钢坯数字化项目数据异常!
  53. **异常详情:**
  54. - **异常信号**:{self.policy_5[name][2] if ccmNo == '5' else self.policy_6[name][2]}
  55. - **异常描述**:{self.policy_5[name][0] if ccmNo == '5' else self.policy_6[name][0]}秒无响应
  56. - **发生时间**:{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}
  57. - **影响范围**:{self.policy_5[name][1] if ccmNo == '5' else self.policy_6[name][1]}
  58. - **处理方法**:{self.policy_5[name][3] if ccmNo == '5' else self.policy_6[name][3]}
  59. ---
  60. > 看门狗信号异常请立即检查,其他异常请先检查是否设备停机或短暂停止'''
  61. response = requests.post(url, json=tmp)
  62. if response.ok and response.json()['errcode'] == 0:
  63. self.logger.warning(f"[WARNING]{str(name)}信号异常,已经提交了报告")
  64. else:
  65. self.logger.warning(f"[WARNING]{str(name)}信号异常,但提交报告失败")
  66. def start_check(self):
  67. while self.threading_sig:
  68. for i, j in self.policy_5.items():
  69. if isinstance(i, tuple):
  70. newdata = []
  71. for k in i:
  72. newdata.append(self.data_5.get_value(k))
  73. newdata = tuple(newdata)
  74. elif isinstance(i, str):
  75. newdata = self.data_5.get_value(i)
  76. else:
  77. warnings.warn('checker模块Error:使用不支持的信号变量类型')
  78. self.logger.error('checker模块Error:使用不支持的信号变量类型')
  79. return None
  80. if newdata != self.value_5[i]:
  81. self.value_5[i] = newdata
  82. self.time_5[i] = time.time()
  83. self.already.discard('5#'+str(i))
  84. if '5#'+str(i) not in self.already and time.time() - self.time_5[i] > j[0]:
  85. self.push(i, '5')
  86. self.already.add('5#'+str(i))
  87. for i, j in self.policy_6.items():
  88. if isinstance(i, tuple):
  89. newdata = []
  90. for k in i:
  91. newdata.append(self.data_6.get_value(k))
  92. newdata = tuple(newdata)
  93. elif isinstance(i, str):
  94. newdata = self.data_6.get_value(i)
  95. else:
  96. warnings.warn('checker模块Error:使用不支持的信号变量类型')
  97. self.logger.error('checker模块Error:使用不支持的信号变量类型')
  98. return None
  99. if newdata != self.value_6[i]:
  100. self.value_6[i] = newdata
  101. self.time_6[i] = time.time()
  102. self.already.discard('6#'+str(i))
  103. if '6#'+str(i) not in self.already and time.time() - self.time_6[i] > j[0]:
  104. self.push(i, '6')
  105. self.already.add('6#'+str(i))
  106. time.sleep(5)
  107. def async_start_check(self):
  108. self.thread = threading.Thread(target=self.start_check)
  109. self.thread.start()
  110. def clear(self):
  111. self.already = set()