| | |
| | | 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 { //待机 |
| | |
| | | // @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, ¶ms) |
| | |
| | | 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()) |
| | |
| | | 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 |
| | | } |
| | |
| | | } |
| | | 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)) |
| | | } |
| | |
| | | } |
| | | 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)) |
| | | } |
| | |
| | | 1000 |
| | | 1001 |
| | | 1002 |
| | | 2000 |
| | | 2001 |
| | | 2002 |
| | |
| | | } |
| | | } |
| | | }, |
| | | "/v1/task/sendProcessParams/{id}": { |
| | | "/v1/task/sendProcessParams": { |
| | | "post": { |
| | | "produces": [ |
| | | "application/json" |
| | |
| | | "type": "string", |
| | | "enum": [ |
| | | "modbusTCP", |
| | | "serial" |
| | | "serial", |
| | | "网络", |
| | | "串口" |
| | | ], |
| | | "x-enum-varnames": [ |
| | | "PlcMethodModbusTCP", |
| | | "PlcMethodSerial" |
| | | "PlcMethodSerial", |
| | | "PlcMethodModbusTCPChinese", |
| | | "PlcMethodSerialChinese" |
| | | ] |
| | | }, |
| | | "constvar.PlcStartAddressType": { |
| | |
| | | } |
| | | } |
| | | }, |
| | | "/v1/task/sendProcessParams/{id}": { |
| | | "/v1/task/sendProcessParams": { |
| | | "post": { |
| | | "produces": [ |
| | | "application/json" |
| | |
| | | "type": "string", |
| | | "enum": [ |
| | | "modbusTCP", |
| | | "serial" |
| | | "serial", |
| | | "网络", |
| | | "串口" |
| | | ], |
| | | "x-enum-varnames": [ |
| | | "PlcMethodModbusTCP", |
| | | "PlcMethodSerial" |
| | | "PlcMethodSerial", |
| | | "PlcMethodModbusTCPChinese", |
| | | "PlcMethodSerialChinese" |
| | | ] |
| | | }, |
| | | "constvar.PlcStartAddressType": { |
| | |
| | | enum: |
| | | - modbusTCP |
| | | - serial |
| | | - 网络 |
| | | - 串口 |
| | | type: string |
| | | x-enum-varnames: |
| | | - PlcMethodModbusTCP |
| | | - PlcMethodSerial |
| | | - PlcMethodModbusTCPChinese |
| | | - PlcMethodSerialChinese |
| | | constvar.PlcStartAddressType: |
| | | enum: |
| | | - 1 |
| | |
| | | summary: 获取任务 |
| | | tags: |
| | | - Task |
| | | /v1/task/sendProcessParams/{id}: |
| | | /v1/task/sendProcessParams: |
| | | post: |
| | | parameters: |
| | | - description: 查询参数 |
| | |
| | | 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() |
| | |
| | | |
| | | 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 { |
| | |
| | | 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++ |
| | |
| | | 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 { |
| | |
| | | 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 |
| | | } |
| | | |