zhangqian
2023-09-15 915253f87d4ef04d886bebb50135d75082ae0eee
换一种方式检查plc连接
10个文件已修改
153 ■■■■ 已修改文件
api/v1/plc.go 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/v1/task.go 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
crontask/cron_task.go 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
datafile/plc_address_value 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/docs.go 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/swagger.json 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/swagger.yaml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pkg/plc/plc4x.go 35 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/plc.go 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/progress.go 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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 { //待机
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
    }
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))
                }
datafile/plc_address_value
@@ -1,3 +1,3 @@
1000
1001
1002
2000
2001
2002
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": {
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": {
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: 查询参数
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 {
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 {
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
}