فهرست منبع

组坯、新分炉功能测试版本

oldwine 5 ماه پیش
والد
کامیت
ccb29a4131
6فایلهای تغییر یافته به همراه228 افزوده شده و 12 حذف شده
  1. 9 0
      conf/5#nodes.csv
  2. 9 0
      conf/6#nodes.csv
  3. 9 3
      main.py
  4. 19 5
      models/billet_counter.py
  5. 155 0
      models/billet_trace_pusher.py
  6. 27 4
      models/data_sender.py

+ 9 - 0
conf/5#nodes.csv

@@ -27,3 +27,12 @@ L5
 L6À­ËÙ,real,136,20,0,4,TRUE,FALSE,500
 L7À­ËÙ,real,137,20,0,4,TRUE,FALSE,500
 L8À­ËÙ,real,138,20,0,4,TRUE,FALSE,500
+ÍÆ¸Ö»ú¼¤¹â,real,360,56,0,4,TRUE,FALSE,500
+L1µ²°å,bool,131,40,0,1,TRUE,FALSE,500
+L2µ²°å,bool,132,40,0,1,TRUE,FALSE,500
+L3µ²°å,bool,133,40,0,1,TRUE,FALSE,500
+L4µ²°å,bool,134,40,0,1,TRUE,FALSE,500
+L5µ²°å,bool,135,40,0,1,TRUE,FALSE,500
+L6µ²°å,bool,136,40,0,1,TRUE,FALSE,500
+L7µ²°å,bool,137,40,0,1,TRUE,FALSE,500
+L8µ²°å,bool,138,40,0,1,TRUE,FALSE,500

+ 9 - 0
conf/6#nodes.csv

@@ -27,3 +27,12 @@ L5
 L6À­ËÙ,real,236,20,0,4,TRUE,FALSE,500
 L7À­ËÙ,real,237,20,0,4,TRUE,FALSE,500
 L8À­ËÙ,real,238,20,0,4,TRUE,FALSE,500
+ÍÆ¸Ö»ú¼¤¹â,real,205,38,0,4,TRUE,FALSE,500
+L1µ²°å,bool,231,40,0,1,TRUE,FALSE,500
+L2µ²°å,bool,232,40,0,1,TRUE,FALSE,500
+L3µ²°å,bool,233,40,0,1,TRUE,FALSE,500
+L4µ²°å,bool,234,40,0,1,TRUE,FALSE,500
+L5µ²°å,bool,235,40,0,1,TRUE,FALSE,500
+L6µ²°å,bool,236,40,0,1,TRUE,FALSE,500
+L7µ²°å,bool,237,40,0,1,TRUE,FALSE,500
+L8µ²°å,bool,238,40,0,1,TRUE,FALSE,500

+ 9 - 3
main.py

@@ -1,5 +1,6 @@
 from models.billet_counter import Counter
 from models.data_sender import Sender
+from models.billet_trace_pusher import Trace_pusher
 from utils.s7data import S7data, S7Client
 from utils.mqttdata import Mqttdata, MqttClient
 from utils.logger import Logger
@@ -67,12 +68,17 @@ sender = Sender(logger_sender)
 sender.set_mqtt_client(mqtt_web)
 
 # debug设置
-# sender.http_flag = False
+sender.http_flag = False
 
 
 ##############################################################
 # 分炉分坯服务
 
-flfp_5 = Counter(data_mes, data_5, 5, logger_5, sender)
+position_5 = [10462, 11553, 12671, 14020, 31641, 16412, 17229, 18809]
+position_6 = [7610, 9175, 10425, 11700, 13000, 14350, 15577, 16952]
 
-flfp_6 = Counter(data_mes, data_6, 6, logger_6, sender)
+pusher_5 = Trace_pusher(data_5, logger_5, sender, position_5)
+pusher_6 = Trace_pusher(data_6, logger_6, sender, position_6)
+
+flfp_5 = Counter(data_mes, data_5, 5, logger_5, sender, pusher_5)
+flfp_6 = Counter(data_mes, data_6, 6, logger_6, sender, pusher_6)

+ 19 - 5
models/billet_counter.py

@@ -2,6 +2,7 @@ from utils.statepoint import *
 from utils.mqttdata import *
 from utils.s7data import *
 from models.data_sender import *
+from models.billet_trace_pusher import *
 import logging
 
 _Debug = 0
@@ -84,12 +85,13 @@ class Counter:
             self.begin_cutting[i].allow_update()
 
 
-    def __init__(self, data_mqtt: Mqttdata, data_s7: S7data, ccmNo, logger: logging.Logger, sender: Sender):
+    def __init__(self, data_mqtt: Mqttdata, data_s7: S7data, ccmNo, logger: logging.Logger, sender: Sender, pusher_trace: Trace_pusher):
         # 模块入口、出口、日志定义
         self._data_mqtt = data_mqtt
         self._data_s7 = data_s7
         self._sender = sender
         self.logger = logger
+        self.send_dst = pusher_trace
 
         self.logger.info(f"[Counter]分炉分坯模块:{ccmNo}号机模块启动")
 
@@ -112,6 +114,8 @@ class Counter:
         self.new_heat = {}
         self.last_cutting_strand = 0
 
+        self.send_list = [[], [], [], [], [], [], [], []]
+
 
     def begin_pour_action(self):
         # 标志是否为铸机开机的第一次开浇
@@ -198,11 +202,17 @@ class Counter:
 
         if cutting_state_heat:
             # 使用sender向外发送信号
-            self.sender.end_cut(cutting_state_heat, cutting_state_heat_index)
+            # self.sender.end_cut(cutting_state_heat, cutting_state_heat_index)
+
+            tmp = self.send_list[i]
+            self.send_list[i] = []
+            tmp.append(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
+            self.send_dst.data_from_casting(i, tmp)
+
             # 检查自己是否是本炉最后一根钢坯
             if self.last_cutting_strand == i+1:
                 self.last_cutting_strand = 0
-                self.sender.heat_last(cutting_state_heat)
+                # self.sender.heat_last(cutting_state_heat)
 
 
     def strand_add(self, sno, sizing, speed):
@@ -239,10 +249,14 @@ class Counter:
             ccmNo = heatData['ccmNo']
             billetNo = heatData['heatNo'] + ccmNo + str(sno) + '{:0>2}'.format(strandIndex)
             self.logger.info(f"[Counter]{sno}流:{heatData['heatNo']}炉第{heatIndex}根计入系统,坯号:{billetNo}")
-            self.sender.begin_cut(heatData, billetNo, heatIndex, sizing, speed)
+
+            # [坯号, 炉次信息, 定尺, 拉速, 开浇时间, 停浇时间]
+            self.send_list[sno-1] = [billetNo, heatData, sizing, speed, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())]
+            # self.sender.begin_cut(heatData, billetNo, heatIndex, sizing, speed)
             # 使用sender发送炉次首次开切信号
             if heatIndex == 1:
-                self.sender.heat_first(heatData)
+                pass
+                # self.sender.heat_first(heatData)
         else:
             self.logger.info(f"[Counter]{sno}流:未知炉第{heatIndex}根,本炉无法计入系统,下一炉开始正常")
 

+ 155 - 0
models/billet_trace_pusher.py

@@ -0,0 +1,155 @@
+import logging
+from utils.statepoint import *
+from utils.s7data import *
+from models.data_sender import *
+
+class Trace_pusher:
+    def __init__(self, data_s7: S7data, logger: logging.Logger, sender: Sender, strand_position: list):
+        self.data_s7 = data_s7
+        self.logger = logger
+        self.sender = sender
+        self.strands = [[], [], [], [], [], [], [], []]
+        self.locks = [threading.Lock() for i in range(8)]
+        self.strand_position = strand_position
+
+        self.billets_wait = []
+        for i in range(8):
+            tmp = self.data_s7.make_point('推钢机激光')
+            tmp.allow_update(False)
+            tmp.set_state(False)
+            self.billets_wait.append(tmp)
+        
+        self.old_heatNo = "00000000"
+        self.current_heatNo = "00000000"
+        self.old_heatData = {}
+        self.current_heatData = {}
+        self.total = 0
+        self.strand = [0, 0, 0, 0, 0, 0, 0, 0]
+        self.count_lock = threading.Lock()
+
+        self.pusher_left_list = []
+        self.pusher_right_list = []
+
+        self.bed_left = []
+        self.bed_right = []
+
+        self.pusher_left = data_s7.make_point('推钢机激光')
+        self.pusher_right = data_s7.make_point('推钢机激光')
+
+        self.pusher_left.set_convertor(lambda data: data < min(self.strand_position))
+        self.pusher_right.set_convertor(lambda data: data > max(self.strand_position))
+        self.pusher_left.set_excite_action(lambda: self.arrive_cooling_bed('left'))
+        self.pusher_right.set_excite_action(lambda: self.arrive_cooling_bed('right'))
+
+        self.barrier = [
+            self.data_s7.make_point('L1挡板'),
+            self.data_s7.make_point('L2挡板'),
+            self.data_s7.make_point('L3挡板'),
+            self.data_s7.make_point('L4挡板'),
+            self.data_s7.make_point('L5挡板'),
+            self.data_s7.make_point('L6挡板'),
+            self.data_s7.make_point('L7挡板'),
+            self.data_s7.make_point('L8挡板')
+        ]
+
+        for i in range(8):
+            self.barrier[i].allow_update(False)
+            self.barrier[i].set_state(False)
+            self.barrier[i].set_convertor(lambda data: not bool(data))
+            self.barrier[i].set_excite_action(lambda i=i: self.barrier_up_action(i))
+            self.barrier[i].set_reset_action(lambda i=i: self.logger.debug(f"{i+1}流挡板关闭"))
+            self.barrier[i].allow_update()
+
+
+    def barrier_up_action(self, i):
+        with self.locks[i]:
+            if self.strands[i]:
+                billetData = self.strands[i]
+                self.strands[i] = []
+                if self.strand_position[i] <= self.pusher_left.data:
+                    self.logger.info(f"[TRACE]{i+1}流钢坯通过挡板进入推钢区域,在推钢机左侧")
+                    self.pusher_left_list.append(billetData)
+                else:
+                    self.logger.info(f"[TRACE]{i+1}流钢坯通过挡板进入推钢区域,在推钢机右侧")
+                    self.pusher_right_list.append(billetData)
+            else:
+                self.logger.error(f"[TRACE]{i+1}流挡板打开但挡板后无已计入系统的钢坯")
+                return None
+            
+    def arrive_cooling_bed(self, direc):
+        with self.count_lock:
+            if direc == 'left':
+                if len(self.pusher_left_list) >= 4:
+                    if len(self.bed_left):
+                        self.logger.warning(f"有冷床上的钢坯无法录入:{'、'.join([i[0] for i in self.bed_right])}")
+                        self.bed_left = []
+                    
+                self.bed_left.extend(self.pusher_left_list)
+                self.pusher_left_list = []
+                if len(self.bed_left) >= 4:
+                    for i in self.bed_left:
+                        if not (i[0].startswith(self.current_heatNo) or i[0].startswith(self.old_heatNo)):
+                            # 换炉代码
+                            self.old_heatNo = self.current_heatNo
+                            self.old_heatData = self.current_heatData
+                            self.current_heatNo = i[0][:8]
+                            self.current_heatData = i[1]
+                            # 上一炉终止信号在这里发
+                            self.total = 0
+                            self.strand = [0, 0, 0, 0, 0, 0, 0, 0]
+                            break
+
+                    tmp = self.bed_left
+                    self.bed_left = []
+                    self.billet_union(tmp)
+
+            elif direc == 'right':
+                if len(self.pusher_right_list) >= 4:
+                    if len(self.bed_right):
+                        self.logger.warning(f"有冷床上的钢坯无法录入:{'、'.join([i[0] for i in self.bed_right])}")
+                        self.bed_right = []
+                    
+                self.bed_right.extend(self.pusher_right_list)
+                self.pusher_right_list = []
+                if len(self.bed_right) >= 4:
+                    for i in self.bed_right:
+                        if not (i[0].startswith(self.current_heatNo) or i[0].startswith(self.old_heatNo)):
+                            # 换炉代码
+                            self.old_heatNo = self.current_heatNo
+                            self.old_heatData = self.current_heatData
+                            self.current_heatNo = i[0][:8]
+                            self.current_heatData = i[1]
+                            # 上一炉终止信号在这里发
+                            self.total = 0
+                            self.strand = [0, 0, 0, 0, 0, 0, 0, 0]
+                            break
+
+                    tmp = self.bed_right
+                    self.bed_right = []
+                    self.billet_union(tmp)
+
+    def billet_union(self, billets):
+        billetsNo = []
+        ccmNo = self.current_heatData['ccmNo']
+        for i in billets:
+            strandNo = i[0][9]
+            self.total += 1
+            self.strand[int(strandNo)] += 1
+            billetNo = self.current_heatNo + ccmNo + strandNo + '{:0>2}'.format(self.strand[int(strandNo)])
+            billetsNo.append(billetNo)
+            self.sender.billet_upload(self.current_heatData, billetNo, self.total, i[2], i[3], i[4], i[5])
+        
+        self.logger.info(f"{self.current_heatNo}炉{len(billets)}根钢坯组成了一夹子:{'、'.join(billetsNo)}")
+
+
+    def data_from_casting(self, i, data):
+        with self.locks[i]:
+            if self.strands[i]:
+                self.logger.warning(f"{i+1}流有未经过挡板的钢坯被后坯顶出系统")
+                self.strands[i] = data
+            else:
+                self.logger.info(f"{i+1}流新增钢坯存储")
+                self.strands[i] = data
+
+
+# [坯号, 炉次信息, 定尺, 拉速, 开浇时间, 停浇时间]

+ 27 - 4
models/data_sender.py

@@ -115,8 +115,9 @@ class Sender:
         self._cache[heat_data.get('heatNo', 'error')] = tmp
         self.send('heat_add', tmp)
 
-    def heat_first(self, heat_data):
-        cuttime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
+    def heat_first(self, heat_data, cuttime = None):
+        if not cuttime:
+            cuttime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
         tmp = self._cache[heat_data['heatNo']]
         tmp['optype'] = 2
         tmp['firstCutTime'] = cuttime
@@ -125,8 +126,9 @@ class Sender:
         self._cache[heat_data.get('heatNo', 'error')] = tmp
         self.send('heat_add', tmp)
 
-    def heat_last(self, heat_data):
-        cuttime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
+    def heat_last(self, heat_data, cuttime = None):
+        if not cuttime:
+            cuttime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
         tmp = self._cache[heat_data['heatNo']]
         tmp['optype'] = 2
         tmp['lastCutTime'] = cuttime
@@ -176,6 +178,27 @@ class Sender:
         self._billet[heat_data.get('heatNo', '')+str(heatnoIndex)] = tmp
         self.send('billet_add', tmp)
 
+    def billet_upload(self, heat_data, billetNo, heatnoIndex, sizing, speed, starttime, stoptime):
+        tmp = self.billet_tangible_temp.copy()
+        tmp['optype'] = 1
+        tmp['heatNo'] = heat_data.get('heatNo', '')
+        tmp['billetNo'] = billetNo
+        tmp['grade'] = heat_data.get('grade', '')
+        tmp['spec'] = heat_data.get('spec', '')
+        tmp['ladleNo'] = heat_data.get('ladleNo', '')
+        tmp['ccmNo'] = heat_data.get('ccmNo', '')
+        tmp['strandNo'] = billetNo[-3]
+        tmp['heatnoIndex'] = heatnoIndex
+        tmp['length'] = sizing
+        tmp['strandnoIndex'] = int(billetNo[-2:])
+        tmp['castingSpeed'] = speed
+        tmp['weight'] = sizing / 1000 * 0.2265
+        tmp['cutStartTime'] = starttime
+        tmp['cutStopTime'] = stoptime
+
+        #此处应存储进数据库
+        self.send('billet_add', tmp)
+
 if __name__ == '__main__':
     mqttcli = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, 'python-mqtt-992-sender_test')
     mqttcli.username_pw_set('admin', '123456')