Bläddra i källkod

添加了车牌读取延迟、步进冷床数据、数据报警模块

oldwine 2 månader sedan
förälder
incheckning
791e948802
7 ändrade filer med 149 tillägg och 5 borttagningar
  1. 10 0
      conf/5#nodes.csv
  2. 2 0
      conf/6#nodes.csv
  3. 8 1
      main.py
  4. 3 3
      models/billet_trace_pusher.py
  5. 102 0
      models/data_checker.py
  6. 1 1
      models/parking.py
  7. 23 0
      utils/s7data.py

+ 10 - 0
conf/5#nodes.csv

@@ -84,3 +84,13 @@ L8
 车2存在,int,307,2,0,2,TRUE,FALSE,500,5
 车3存在,int,308,2,0,2,TRUE,FALSE,500,5
 车4存在,int,309,2,0,2,TRUE,FALSE,500,5
+定尺看门狗1,int,100,0,0,2,TRUE,FALSE,500,5
+定尺看门狗2,int,101,0,0,2,TRUE,FALSE,500,5
+车位1视觉看门狗,int,306,0,0,2,TRUE,FALSE,500,5
+车位2视觉看门狗,int,307,0,0,2,TRUE,FALSE,500,5
+车位3视觉看门狗,int,308,0,0,2,TRUE,FALSE,500,5
+车位4视觉看门狗,int,309,0,0,2,TRUE,FALSE,500,5
+车位1车牌看门狗,int,310,0,0,2,TRUE,FALSE,500,5
+车位2车牌看门狗,int,311,0,0,2,TRUE,FALSE,500,5
+车位3车牌看门狗,int,312,0,0,2,TRUE,FALSE,500,5
+车位4车牌看门狗,int,313,0,0,2,TRUE,FALSE,500,5

+ 2 - 0
conf/6#nodes.csv

@@ -44,3 +44,5 @@ L5
 L6坯头位置,int,201,4,0,2,TRUE,FALSE,500,3
 L7坯头位置,int,201,6,0,2,TRUE,FALSE,500,3
 L8坯头位置,int,201,8,0,2,TRUE,FALSE,500,3
+定尺看门狗1,int,200,0,0,2,TRUE,FALSE,500,3
+定尺看门狗2,int,201,0,0,2,TRUE,FALSE,500,3

+ 8 - 1
main.py

@@ -6,6 +6,7 @@ from utils.mqttdata import Mqttdata, MqttClient
 from utils.logger import Logger
 from models.parking import Parking
 from models.overhead_crane import Crane
+from models.data_checker import Checker
 
 ##############################################################
 # 日志配置
@@ -98,4 +99,10 @@ parking = Parking(data_5, sender)
 ##############################################################
 # 天车跟踪服务
 
-crane = Crane(data_5, pusher_5, pusher_6, parking, sender, logger_trace)
+crane = Crane(data_5, pusher_5, pusher_6, parking, sender, logger_trace)
+
+##############################################################
+# 数据警报服务
+
+checker = Checker(data_5, data_6, logger_sender)
+checker.async_start_check()

+ 3 - 3
models/billet_trace_pusher.py

@@ -388,8 +388,8 @@ class Trace_pusher:
         return []
     
     def billet_to_stack(self, stackNo, billets):
-        self.logger.info(f"有钢坯放入{stackNo}堆垛")
-
-
+        if billets:
+            self.logger.info(f"有钢坯放入{stackNo}堆垛")
+            self.sender.stack_add('6', billets, "", time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), "6#小冷床(右)", '501堆垛')
 
 # [坯号, 炉次信息, 定尺, 拉速, 开切时间, 停切时间]

+ 102 - 0
models/data_checker.py

@@ -0,0 +1,102 @@
+from utils.s7data import S7data
+from utils.logger import Logger
+import requests, time, threading
+
+class Checker:
+    def __init__(self, data_5: S7data, data_6: S7data, logger: Logger):
+        self.data_5 = data_5
+        self.data_6 = data_6
+        self.logger = logger
+
+        self.already = set()
+
+        self.policy_5 = {
+            '定尺看门狗1': [10, '5#机1-4流定尺数据'],
+            '定尺看门狗2': [10, '5#机5-8流定尺数据'],
+            '推钢机激光': [1800, '5#机组坯、装运等除直轧外所有数据'],
+            '天车A1位置': [1800, '5#机堆垛、装车数据'],
+            '天车A2位置': [1800, '5#、6#机堆垛、装车、高线数据'],
+            '天车A3位置': [1800, '6#机堆垛、装车、高线数据'],
+            '车位1视觉看门狗': [10, '5#机车位1到站离站信号'],
+            '车位2视觉看门狗': [10, '6#机车位2到站离站信号'],
+            '车位3视觉看门狗': [10, '6#机车位3到站离站信号'],
+            '车位4视觉看门狗': [10, '6#机车位4到站离站信号'],
+            '车位1车牌看门狗': [10, '5#机车位1车牌识别'],
+            '车位2车牌看门狗': [10, '6#机车位2车牌识别'],
+            '车位3车牌看门狗': [10, '6#机车位3车牌识别'],
+            '车位4车牌看门狗': [10, '6#机车位4车牌识别']
+        }
+
+        self.policy_6 = {
+            '定尺看门狗1': [10, '6#机1-4流定尺数据'],
+            '定尺看门狗2': [10, '6#机5-8流定尺数据'],
+            '推钢机激光': [300, '6#机钢坯基础信息、组坯等所有数据']
+        }
+
+        self.time_5 = {}
+        self.time_6 = {}
+
+        self.value_5 = {}
+        self.value_6 = {}
+
+        now = time.time()
+        for i in self.policy_5.keys():
+            self.time_5[i] = now
+            self.value_5[i] = 0
+        for i in self.policy_6.keys():
+            self.time_6[i] = now
+            self.value_6[i] = 0
+
+        self.threading_sig = True
+
+    def push(self, name, ccmNo):
+        url = 'https://oapi.dingtalk.com/robot/send?access_token=60fbad9923c55730485ead3270621fd0a03fdc28d6a8e78a85a4ce4d0ee727dd'
+        tmp = {}
+        tmp['msgtype'] = 'markdown'
+        tmp['markdown'] = {}
+        tmp['markdown']['title'] = '数据异常警告'
+        tmp['markdown']['text'] = f'''#### 警告:钢坯数字化项目数据异常!
+
+**异常详情:**
+- **异常信号**:{name}
+- **异常描述**:{self.policy_5[name][0] if ccmNo == '5' else self.policy_6[name][0]}秒无响应
+- **发生时间**:{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}
+- **影响范围**:{self.policy_5[name][1] if ccmNo == '5' else self.policy_6[name][1]}
+
+---
+
+> 看门狗信号异常请立即检查,其他异常请先检查是否设备停机或短暂停止'''
+        response = requests.post(url, json=tmp)
+        if response.ok and response.json()['errcode'] == 0:
+            self.logger.warning(f"[WARNING]{name}信号异常,已经提交了报告")
+        else:
+            self.logger.warning(f"[WARNING]{name}信号异常,但提交报告失败")
+
+    def start_check(self):
+        while self.threading_sig:
+            for i, j in self.policy_5.items():
+                newdata = self.data_5.get_value(i)
+                if newdata != self.value_5[i]:
+                    self.value_5[i] = newdata
+                    self.time_5[i] = time.time()
+                if '5#'+i not in self.already and time.time() - self.time_5[i] > j[0]:
+                    self.push(i, '5')
+                    self.already.add('5#'+i)
+
+            for i, j in self.policy_6.items():
+                newdata = self.data_6.get_value(i)
+                if newdata != self.value_6[i]:
+                    self.value_6[i] = newdata
+                    self.time_6[i] = time.time()
+                if '6#'+i not in self.already and time.time() - self.time_6[i] > j[0]:
+                    self.push(i, '6')
+                    self.already.add('6#'+i)
+
+            time.sleep(5)
+
+    def async_start_check(self):
+        self.thread = threading.Thread(target=self.start_check)
+        self.thread.start()
+
+    def clear(self):
+        self.already = set()

+ 1 - 1
models/parking.py

@@ -46,7 +46,7 @@ class Parking:
         else:
             valuedata = self.value_a[i]
 
-        time.sleep(2)
+        time.sleep(3)
         send_flag = False
         with self.lock:
             if self.current_car[i] != valuedata.data:

+ 23 - 0
utils/s7data.py

@@ -60,6 +60,29 @@ class S7data:
 
     def get_S7Client(self):
         return self.S7Client
+    
+    def get_value(self, name):
+        if self.nodes[name]['type'] == 'int':
+            data = snap7.util.get_int(self.node_data[name], 0)
+        elif self.nodes[name]['type'] == 'dint':
+            data = snap7.util.get_dint(self.node_data[name], 0)
+        elif self.nodes[name]['type'] == 'bool':
+            data = snap7.util.get_bool(self.node_data[name], 0, int(self.nodes[name]['offset']))
+        elif self.nodes[name]['type'] == 'boollist':
+            data = [(self.node_data[name][0] >> i) & 1 for i in range(8)]
+        elif self.nodes[name]['type'] == 'real':
+            data = snap7.util.get_real(self.node_data[name], 0)
+        elif self.nodes[name]['type'] == 'string':
+            data = self.node_data[name][2:2+int.from_bytes(self.node_data[name][1:2])].decode('gbk')
+        elif self.nodes[name]['type'] == 'wstring':
+            data = self.node_data[name][4:].decode(encoding='utf-16be')
+        else:
+            warnings.warn('暂不支持的类型:' + self.nodes[name]['type'])
+            if self.logger:
+                self.logger.error('暂不支持的类型:' + self.nodes[name]['type'])
+            return None
+        
+        return data
 
     def send(self, name):
         if self.nodes[name]['type'] == 'int':