From 915253f87d4ef04d886bebb50135d75082ae0eee Mon Sep 17 00:00:00 2001
From: zhangqian <zhangqian@123.com>
Date: 星期五, 15 九月 2023 13:37:22 +0800
Subject: [PATCH] 换一种方式检查plc连接

---
 api/v1/plc.go              |    4 
 service/plc.go             |   20 +++++-
 pkg/plc/plc4x.go           |   35 ++++++++++-
 service/progress.go        |   30 +++++----
 datafile/plc_address_value |    6 +-
 docs/swagger.yaml          |    6 +
 crontask/cron_task.go      |   16 ++++-
 docs/docs.go               |   10 ++-
 api/v1/task.go             |   16 ++++
 docs/swagger.json          |   10 ++-
 10 files changed, 112 insertions(+), 41 deletions(-)

diff --git a/api/v1/plc.go b/api/v1/plc.go
index a837e7a..782e28c 100644
--- a/api/v1/plc.go
+++ b/api/v1/plc.go
@@ -42,8 +42,8 @@
 	plcStatus := 1 //鏂紑杩炴帴
 	ipAddr := fmt.Sprintf("%s:%v", plcConfig.Address, plcConfig.Port)
 
-	conn, err := plc.GetModbusConnection(ipAddr)
-	if err == nil && conn.IsConnected() {
+	_, err := plc.GetModbusConnection(ipAddr)
+	if err == nil {
 		if resp.FinishNumber > 0 { //鐢熶骇
 			plcStatus = 2
 		} else { //寰呮満
diff --git a/api/v1/task.go b/api/v1/task.go
index 0552884..bbb328d 100644
--- a/api/v1/task.go
+++ b/api/v1/task.go
@@ -187,7 +187,7 @@
 // @Produce   application/json
 // @Param     object  body    request.SendProcessParams true  "鏌ヨ鍙傛暟"
 // @Success   200   {object}  contextx.Response{service.GetProcessModel}  "鎴愬姛"
-// @Router    /v1/task/sendProcessParams/{id} [post]
+// @Router    /v1/task/sendProcessParams [post]
 func (slf *TaskApi) TaskStart(c *gin.Context) {
 	var params request.SendProcessParams
 	ctx, ok := contextx.NewContext(c, &params)
@@ -227,7 +227,7 @@
 		if err != nil {
 			return err
 		}
-		return service.NewProgressService().AddProgress(db, procedure, order)
+		return service.NewProgressService().Upsert(db, procedure, order)
 	})
 	if err != nil {
 		logx.Errorf("SendProcessParams update order and procedure status error:%v", err.Error())
@@ -243,6 +243,18 @@
 	err = SendParams(processModel.ParamsMap, plcConfig)
 	if err != nil {
 		logx.Errorf("SendProcessParams: %v", err.Error())
+		err = model.WithTransaction(func(db *gorm.DB) error {
+			err = taskService.UpdateProcedureStatusAndPosition(db, params.ProcedureId, model.ProcedureStatusWaitProcess, params.Position)
+			if err != nil {
+				return err
+			}
+			procedure.Position = params.Position
+			err = taskService.UpdateOrderStatus(db, order.ID, model.OrderStatusWaitProcess)
+			if err != nil {
+				return err
+			}
+			return nil
+		})
 		ctx.FailWithMsg(ecode.NeedConfirmedErr, "绯熺硶锛屽伐鑹轰笅鍙戝け璐ャ��")
 		return
 	}
diff --git a/crontask/cron_task.go b/crontask/cron_task.go
index 505156d..968abfc 100644
--- a/crontask/cron_task.go
+++ b/crontask/cron_task.go
@@ -31,8 +31,12 @@
 		}
 		for _, addressItem := range plcConfig.Details {
 			if addressItem.FieldName == constvar.PlcStartAddressTypeFinishNumber {
-				finishNumber, err := service.PlcReadDirect(plcConfig, addressItem.StartAddress, addressItem.Position)
-				if err == nil && finishNumber != 0 {
+				value, err := service.PlcReadDirect(plcConfig, addressItem.StartAddress, addressItem.Length, addressItem.Type)
+				if err != nil {
+					continue
+				}
+				finishNumber := cast.ToInt64(value)
+				if finishNumber != 0 {
 					service.PlcCacheSet(addressItem.Position, constvar.PlcCacheKeyFinishNumber, finishNumber)
 					_ = service.NewProgressService().UpdateProgress(addressItem.Position, cast.ToInt64(finishNumber))
 				}
@@ -52,8 +56,12 @@
 		}
 		for _, addressItem := range plcConfig.Details {
 			if addressItem.FieldName == constvar.PlcStartAddressTypeTotalNumber {
-				totalNumber, err := service.PlcReadDirect(plcConfig, addressItem.StartAddress, addressItem.Position)
-				if err == nil && totalNumber != 0 {
+				value, err := service.PlcReadDirect(plcConfig, addressItem.StartAddress, addressItem.Length, addressItem.Type)
+				if err != nil {
+					continue
+				}
+				totalNumber := cast.ToInt64(value)
+				if totalNumber != 0 {
 					service.PlcCacheSet(addressItem.Position, constvar.PlcCacheKeyTotalNumber, totalNumber)
 					_ = service.NewProgressService().UpdateProgress(addressItem.Position, cast.ToInt64(totalNumber))
 				}
diff --git a/datafile/plc_address_value b/datafile/plc_address_value
index 3a9e4ec..b6d91da 100644
--- a/datafile/plc_address_value
+++ b/datafile/plc_address_value
@@ -1,3 +1,3 @@
-1000
-1001
-1002
\ No newline at end of file
+2000
+2001
+2002
\ No newline at end of file
diff --git a/docs/docs.go b/docs/docs.go
index dc275bb..2f9b1f7 100644
--- a/docs/docs.go
+++ b/docs/docs.go
@@ -439,7 +439,7 @@
                 }
             }
         },
-        "/v1/task/sendProcessParams/{id}": {
+        "/v1/task/sendProcessParams": {
             "post": {
                 "produces": [
                     "application/json"
@@ -612,11 +612,15 @@
             "type": "string",
             "enum": [
                 "modbusTCP",
-                "serial"
+                "serial",
+                "缃戠粶",
+                "涓插彛"
             ],
             "x-enum-varnames": [
                 "PlcMethodModbusTCP",
-                "PlcMethodSerial"
+                "PlcMethodSerial",
+                "PlcMethodModbusTCPChinese",
+                "PlcMethodSerialChinese"
             ]
         },
         "constvar.PlcStartAddressType": {
diff --git a/docs/swagger.json b/docs/swagger.json
index 3566fd0..47b9642 100644
--- a/docs/swagger.json
+++ b/docs/swagger.json
@@ -427,7 +427,7 @@
                 }
             }
         },
-        "/v1/task/sendProcessParams/{id}": {
+        "/v1/task/sendProcessParams": {
             "post": {
                 "produces": [
                     "application/json"
@@ -600,11 +600,15 @@
             "type": "string",
             "enum": [
                 "modbusTCP",
-                "serial"
+                "serial",
+                "缃戠粶",
+                "涓插彛"
             ],
             "x-enum-varnames": [
                 "PlcMethodModbusTCP",
-                "PlcMethodSerial"
+                "PlcMethodSerial",
+                "PlcMethodModbusTCPChinese",
+                "PlcMethodSerialChinese"
             ]
         },
         "constvar.PlcStartAddressType": {
diff --git a/docs/swagger.yaml b/docs/swagger.yaml
index fa76802..4f651d1 100644
--- a/docs/swagger.yaml
+++ b/docs/swagger.yaml
@@ -68,10 +68,14 @@
     enum:
     - modbusTCP
     - serial
+    - 缃戠粶
+    - 涓插彛
     type: string
     x-enum-varnames:
     - PlcMethodModbusTCP
     - PlcMethodSerial
+    - PlcMethodModbusTCPChinese
+    - PlcMethodSerialChinese
   constvar.PlcStartAddressType:
     enum:
     - 1
@@ -632,7 +636,7 @@
       summary: 鑾峰彇浠诲姟
       tags:
       - Task
-  /v1/task/sendProcessParams/{id}:
+  /v1/task/sendProcessParams:
     post:
       parameters:
       - description: 鏌ヨ鍙傛暟
diff --git a/pkg/plc/plc4x.go b/pkg/plc/plc4x.go
index 529c516..06f6c8e 100644
--- a/pkg/plc/plc4x.go
+++ b/pkg/plc/plc4x.go
@@ -30,7 +30,18 @@
 	defer cm.mu.Unlock()
 
 	conn, ok := cm.connections[address]
-	return conn, ok
+	if !ok {
+		return nil, false
+	}
+	connOK, err := cm.CheckConnect(conn, time.Second*1)
+	if err != nil {
+		logx.Errorf("ping plc err:%v", err.Error())
+		return nil, false
+	}
+	if connOK {
+		return conn, ok
+	}
+	return nil, false
 }
 
 var connectionManager = newPlcConnectionManager()
@@ -41,14 +52,28 @@
 
 	cm.connections[address] = connection
 }
+
+func (cm *ConnectionManager) CheckConnect(conn plc4go.PlcConnection, timeout time.Duration) (bool, error) {
+	pingCh := conn.Ping()
+	timer := time.NewTimer(timeout)
+
+	select {
+	case err := <-pingCh:
+		if err == nil {
+			return true, nil
+		}
+		return false, err.GetErr()
+	case <-timer.C:
+		return false, fmt.Errorf("connection timed out after %s", timeout)
+	}
+}
+
 func GetModbusConnection(ipAddr string) (plc4go.PlcConnection, error) {
 	if conn, ok := connectionManager.GetConnection(ipAddr); ok {
-		if conn.IsConnected() {
-			return conn, nil
-		}
+		return conn, nil
 	}
 	// 鍒涘缓涓�涓笂涓嬫枃锛屽苟璁剧疆 3 绉掕秴鏃�
-	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
+	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
 	defer cancel()
 	conn, err := newGetModbusConnection(ctx, ipAddr)
 	if err != nil {
diff --git a/service/plc.go b/service/plc.go
index 0e5e49f..48292b2 100644
--- a/service/plc.go
+++ b/service/plc.go
@@ -145,12 +145,13 @@
 	return
 }
 
-func PlcReadDirect(plcConfig *model.DevicePlc, address int, dataLength int) (val interface{}, err error) {
+func PlcReadDirect(plcConfig *model.DevicePlc, address int, dataLength int, valueType constvar.PlcStartAddressValueType) (val interface{}, err error) {
 	var (
 		ipAddr string
 	)
 
 	if plcConfig.CurrentTryTimes > plcConfig.MaxTryTimes {
+		logx.Errorf("plc read try time beyond max try times, err:%v", plcConfig.CurrentErr)
 		return nil, plcConfig.CurrentErr
 	}
 	plcConfig.CurrentTryTimes++
@@ -158,15 +159,24 @@
 		ipAddr = fmt.Sprintf("%s:%v", plcConfig.Address, plcConfig.Port)
 		conn, err := plc.GetModbusConnection(ipAddr)
 		if err != nil {
-			logx.Errorf("plc write failed, 杩炴帴plc澶辫触: %v", err.Error())
 			plcConfig.CurrentErr = err
-			return PlcReadDirect(plcConfig, address, dataLength)
+			return PlcReadDirect(plcConfig, address, dataLength, valueType)
 		}
 		value, err := plc.ReadHoldingRegister(conn, address, dataLength)
 		if err != nil {
-			logx.Errorf("plc read failed, address: %v, err: %v", address, err.Error())
 			plcConfig.CurrentErr = err
-			return PlcReadDirect(plcConfig, address, dataLength)
+			return PlcReadDirect(plcConfig, address, dataLength, valueType)
+		}
+		switch valueType {
+		case constvar.PlcStartAddressValueTypeString:
+			return string(value), nil
+		case constvar.PlcStartAddressValueTypeInt:
+			if len(value) == 2 {
+				return int(binary.BigEndian.Uint16(value)), nil
+			} else {
+				logx.Errorf("plc read get an unknown int value: %v, address:%v", value, address)
+				return nil, errors.New(fmt.Sprintf("unknown int value锛�%v", value))
+			}
 		}
 		logx.Infof("plc read ok, address: %v, result: %v", address, value)
 	} else if plcConfig.Method == constvar.PlcMethodSerial {
diff --git a/service/progress.go b/service/progress.go
index 972a248..7d39cfa 100644
--- a/service/progress.go
+++ b/service/progress.go
@@ -13,20 +13,24 @@
 	return &ProgressService{}
 }
 
-func (slf ProgressService) AddProgress(db *gorm.DB, procedure *model.Procedures, order *model.Order) error {
-	progress := &model.ProductionProgress{
-		WorkOrderID:   procedure.WorkOrderID,
-		OrderID:       procedure.OrderID,
-		ProcedureID:   procedure.ProceduresInfo.ProcedureID,
-		DeviceID:      procedure.DeviceID,
-		TotalQuantity: order.Amount.IntPart(),
-		Position:      procedure.Position,
+func (slf ProgressService) Upsert(db *gorm.DB, procedure *model.Procedures, order *model.Order) error {
+	_, err := model.NewProductionProgressSearch(db).SetProcedureId(procedure.ProcedureID).SetWorkOrderId(procedure.WorkOrderID).First()
+	if err == gorm.ErrRecordNotFound {
+		progress := &model.ProductionProgress{
+			WorkOrderID:   procedure.WorkOrderID,
+			OrderID:       procedure.OrderID,
+			ProcedureID:   procedure.ProceduresInfo.ProcedureID,
+			DeviceID:      procedure.DeviceID,
+			TotalQuantity: order.Amount.IntPart(),
+			Position:      procedure.Position,
+		}
+		err := model.NewProductionProgressSearch(db).Create(progress)
+		if err != nil {
+			return err
+		}
+		ProgressCacheSet(procedure.Position, progress)
 	}
-	err := model.NewProductionProgressSearch(db).Create(progress)
-	if err != nil {
-		return err
-	}
-	ProgressCacheSet(procedure.Position, progress)
+
 	return nil
 }
 

--
Gitblit v1.8.0