Example #1
0
 public BllResult CopyEquipment(EquipmentType equipmentType)
 {
     using (IDbConnection connection = AppSession.Dal.GetConnection())
     {
         IDbTransaction transaction = null;
         try
         {
             connection.Open();
             transaction = connection.BeginTransaction();
             var temp = AppSession.Dal.GetCommonModelByCondition <EquipmentType>($"where id = {equipmentType.Id}", connection, transaction);
             if (temp.Success)
             {
                 var e     = temp.Data[0];
                 var temp2 = AppSession.Dal.GetCommonModelByCondition <EquipmentTypeTemplate>($"where equipmentTypeId = {e.Id}", connection, transaction);
                 if (temp2.Success)
                 {
                     var props = temp2.Data;
                     //e.Id = null;
                     e.Code = e.Code + "2";
                     var temp3 = AppSession.Dal.InsertCommonModel <EquipmentType>(e, connection, transaction);
                     if (temp3.Success)
                     {
                         props.ForEach(t =>
                         {
                             t.EquipmentTypeId = temp3.Data.Value;
                         });
                         foreach (var item in props)
                         {
                             var temp4 = AppSession.Dal.InsertCommonModel <EquipmentTypeTemplate>(item, connection, transaction);
                             if (!temp4.Success)
                             {
                                 transaction?.Rollback();
                                 return(BllResultFactory.Error($"复制出错:{temp4.Msg}"));
                             }
                         }
                         transaction.Commit();
                         return(BllResultFactory.Sucess());
                     }
                     else
                     {
                         transaction?.Rollback();
                         return(BllResultFactory.Error($"复制出错:{temp3.Msg}"));
                     }
                 }
                 else
                 {
                     transaction?.Rollback();
                     return(BllResultFactory.Error($"复制出错:{temp2.Msg}"));
                 }
             }
             else
             {
                 transaction?.Rollback();
                 return(BllResultFactory.Error($"复制出错:{temp.Msg}"));
             }
         }
         catch (Exception ex)
         {
             transaction?.Rollback();
             return(BllResultFactory.Error($"复制出错:{ex.Message}"));
         }
     }
 }
Example #2
0
        public BllResult SyncEquipmentProp(int?id, string plcDb)
        {
            using (IDbConnection connection = AppSession.Dal.GetConnection())
            {
                IDbTransaction tran = null;
                try
                {
                    connection.Open();
                    tran = connection.BeginTransaction();

                    //现获取这个设备,防止同步删除
                    var a = AppSession.Dal.GetCommonModelByCondition <Equipment>($"where id = {id}");
                    if (!a.Success)
                    {
                        tran.Rollback();
                        return(BllResultFactory.Error("同步失败,设备已被同步删除"));
                    }
                    var equipment = a.Data[0];
                    //查询对应模板的属性
                    var b = AppSession.Dal.GetCommonModelByCondition <EquipmentTypeTemplate>($"where equipmentTypeId = {equipment.EquipmentTypeId}");
                    if (!b.Success)
                    {
                        tran.Rollback();
                        return(BllResultFactory.Error("同步失败,设备无模板属性"));
                    }
                    var templateProps = b.Data;
                    var c             = AppSession.Dal.GetCommonModelByCondition <EquipmentProp>($"where equipmentId = {equipment.Id}");
                    var props         = new List <EquipmentProp>();
                    if (c.Success)
                    {
                        props = c.Data;
                    }
                    var idsFordelete = props.Where(t => !templateProps.Exists(i => i.Id == t.EquipmentTypeTemplateId)).Select(t => t.Id).ToList();
                    if (idsFordelete != null && idsFordelete.Count > 0)
                    {
                        connection.DeleteList <EquipmentProp>("where id in @ids", new { ids = idsFordelete }, tran);
                    }
                    var propForAdd = templateProps.Where(t => !props.Exists(i => i.EquipmentTypeTemplateId == t.Id)).ToList();
                    List <EquipmentProp> propListToAdd = new List <EquipmentProp>();
                    foreach (var item in propForAdd)
                    {
                        EquipmentProp equipmentProp = new EquipmentProp();
                        equipmentProp.EquipmentId               = equipment.Id;
                        equipmentProp.EquipmentTypeTemplateId   = item.Id;
                        equipmentProp.EquipmentTypeTemplateCode = item.Code;
                        equipmentProp.ServerHandle              = 0;
                        if (string.IsNullOrWhiteSpace(plcDb) || !string.IsNullOrWhiteSpace(item.Address))
                        {
                            equipmentProp.Address = item.Address;
                        }
                        else
                        {
                            switch (item.DataType)
                            {
                            case "BOOL": { equipmentProp.Address = plcDb + "X" + item.Offset; break; }

                            case "BYTE": { equipmentProp.Address = plcDb + "B" + item.Offset; break; }

                            case "INT": { equipmentProp.Address = plcDb + "W" + item.Offset; break; }

                            case "DINT": { equipmentProp.Address = plcDb + "D" + item.Offset; break; }

                            case "CHAR": { equipmentProp.Address = plcDb + "CHAR" + item.Offset + ",20"; break; }

                            default: { equipmentProp.Address = item.Address; break; }
                            }
                        }

                        equipmentProp.Value      = "";
                        equipmentProp.Remark     = item.Name;
                        equipmentProp.CreateTime = DateTime.Now;
                        equipmentProp.CreateBy   = "";
                        propListToAdd.Add(equipmentProp);
                    }
                    propListToAdd.ForEach(t => connection.Insert <EquipmentProp>(t, tran));
                    tran.Commit();
                    return(BllResultFactory.Sucess("成功"));
                }
                catch (Exception ex)
                {
                    tran?.Rollback();
                    AppSession.LogService.WriteDBExceptionLog(ex);
                    return(BllResultFactory.Error($"删除失败:{ex.Message}"));
                }
            }
        }
Example #3
0
        /// <summary>
        /// 控制逻辑实现
        /// </summary>
        /// <param name="srm"></param>
        /// <param name="plc"></param>
        /// <returns></returns>
        public BllResult ExcuteSingle(Equipment srm, List <Equipment> allEquipments, IPLC plc)
        {
            //联机、无故障
            if (Validate(srm).Success)
            {
                #region 对于单叉堆垛机,判断这个货叉有误故障

                if (srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.Fork1TotalError.ToString()).Value == "True")
                {
                    //如果报有故障,则返回
                    return(BllResultFactory.Error("货叉1故障"));
                }

                #endregion

                #region 任务执行判断
                if (srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.Fork1TaskExcuteStatus.ToString()).Value == SRMTaskExcuteStatus.任务执行中.GetIndexString())
                {
                    //任务执行中就return
                    return(BllResultFactory.Sucess());
                }
                if (srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.Fork1TaskExcuteStatus.ToString()).Value == SRMTaskExcuteStatus.任务中断_出错.GetIndexString())
                {
                    //由人工处理,一般为空出和重入
                    return(BllResultFactory.Sucess());
                }
                if (srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.Fork1TaskExcuteStatus.ToString()).Value == SRMTaskExcuteStatus.发任务错误.GetIndexString())
                {
                    //由人工处理,需要重新下发任务
                    return(BllResultFactory.Sucess());
                }
                #endregion

                #region 任务,货位和本巷道的其他设备

                //找出所有未完成的任务
                var tasksResult = AppSession.Dal.GetCommonModelByCondition <TaskEntity>($"where taskStatus < {TaskEntityStatus.任务完成.GetIndexInt()} " +
                                                                                        $"and taskStatus>={TaskEntityStatus.下发任务.GetIndexInt()} and deleted = 0 and warehouseCode='{AppSession.WarehouseCode}'");
                if (!tasksResult.Success)
                {
                    //如果没有找到任务就直接返回
                    return(BllResultFactory.Error(tasksResult.Msg));
                }
                //找出同巷道的库位,考虑到可能多个巷道移库,这里分别查询出所有库位和当前堆垛机所在巷道的库位
                var locationsResult = AppSession.LocationService.GetAllLocations(null, null, null, null, null, null, null, srm.WarehouseCode);
                if (!locationsResult.Success)
                {
                    return(BllResultFactory.Error(locationsResult.Msg));
                }
                //所有库位
                var allLocations = locationsResult.Data;
                //本巷道库位
                var locationsRoadWay = allLocations.Where(t => t.RoadWay == srm.RoadWay).ToList();
                //找出本巷道的所有设备
                var equipmentsRoadWay = allEquipments.Where(t => t.RoadWay == srm.RoadWay && t.WarehouseCode == srm.WarehouseCode).ToList();
                //可用的可出站台
                //hack:注意,此处针对每个巷道均需要配置StationStatusMonitor!如果没有配置,则可出站台为空集合;
                var stationOutStatusMonitor = equipmentsRoadWay.Find(a => a.EquipmentType.Code == "StationStatusMonitor");
                var availableOutStation     = stationOutStatusMonitor == null ? new List <Equipment>() : equipmentsRoadWay.Where(t => t.EquipmentType.Code.Contains("Station") &&
                                                                                                                                 stationOutStatusMonitor.EquipmentProps.
                                                                                                                                 Count(b => b.EquipmentTypeTemplateCode == t.StationIndex.ToString() && b.Value == StationTaskLimit.可出.GetIndexString()) > 0).ToList();

                //hack:这里筛选本巷道或关联到本巷道的任务,规则为起始或目标库位,所以,当将来出现跨巷道移库时,需要特别处理跨巷道移库任务
                var tasks = tasksResult.Data.Where(t => locationsRoadWay.Count(a => a.Code == t.FromLocationCode || a.Code == t.ToLocationCode) > 0).ToList();

                //筛选任务,任务的前置任务如果存在,则其前置任务需要大于完成状态
                tasks = tasks.Where(t =>
                {
                    if (t.PreTaskId != 0)
                    {
                        var tempResult = AppSession.Dal.GetCommonModelByCondition <TaskEntity>($"where id = {t.PreTaskId}");
                        if (tempResult.Success)
                        {
                            var innerTask = tempResult.Data[0];
                            if (innerTask.TaskStatus >= (int)TaskEntityStatus.任务完成)
                            {
                                return(true);
                            }
                            else
                            {
                                return(false);
                            }
                        }
                        else
                        {
                            Logger.Log($"未找到任务{t.Id},远程任务号:{t.RemoteTaskNo}的前置远程任务:{t.PreRemoteTaskNo},前置内部任务号:{t.PreTaskId},该任务不允许执行。如果要执行,请取消其前置任务号", LogLevel.Warning);
                            return(false);
                        }
                    }
                    else
                    {
                        return(true);
                    }
                }).ToList();

                #endregion

                //堆垛机待机情况下
                string Fork1TaskExecuteStatus = srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.Fork1TaskExcuteStatus.ToString()).Value;
                if (Fork1TaskExecuteStatus == SRMTaskExcuteStatus.待机.GetIndexString())
                {
                    //货叉任务待机时,可执行放和取任务,同时当执行完成时,交互后堆垛机会从任务完成更新为待机
                    //均判断put放货任务标志
                    //响应任务删除
                    string WcsFork1TaskFlag = srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.WCSPutFork1TaskFlag.ToString()).Value;
                    if (WcsFork1TaskFlag == SRMForkTaskFlag.除任务.GetIndexString())
                    {
                        return(ClearWCSDataS(srm, plc));
                    }
                    //响应任务完成
                    string WcsTaskAccount = srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.WCSTaskCompleteFlag.ToString()).Value;
                    if (WcsTaskAccount == SRMForkTaskFlag.任务完成.GetIndexString())
                    {
                        return(ClearWCSDataS(srm, plc));
                    }
                    //响应无任务且货叉在中心
                    else if (WcsFork1TaskFlag == SRMForkTaskFlag.无任务.GetIndexString() && srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.Fork1Center.ToString()).Value == "True")
                    {
                        //hack:单任务由人员手动处理,不重发
                        //获取需要下发给堆垛机的任务
                        if (srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.Fork1HasPallet.ToString()).Value == "True")
                        {
                            Logger.Log($"堆垛机{srm.Name}显示货叉上有货且无任务,状态错误", LogLevel.Error);
                            return(BllResultFactory.Error());
                        }
                        else
                        {
                            //判断任务限制情况
                            var tempTasks = tasks;
                            //完全空闲的堆垛机实际只执行取货任务,则为库外取与库内取两种
                            //找出下发状态的待取的离堆垛机最近的任务,并且对应站台口需要可用
                            var task1s = tempTasks.Where(t => t.TaskStatus == TaskEntityStatus.发任务.GetIndexInt() &&
                                                         (t.TaskType == TaskType.出库查看.GetIndexInt() ||
                                                          t.TaskType == TaskType.分拣出库.GetIndexInt() ||
                                                          t.TaskType == TaskType.整盘出库.GetIndexInt() ||
                                                          t.TaskType == TaskType.盘点.GetIndexInt() ||
                                                          t.TaskType == TaskType.空容器出库.GetIndexInt() ||
                                                          t.TaskType == TaskType.补充入库.GetIndexInt() ||
                                                          t.TaskType == TaskType.移库.GetIndexInt()) &&
                                                         locationsRoadWay.Exists(a => a.Code == t.FromLocationCode)).ToList();
                            task1s.ForEach(t =>
                            {
                                t.FromLocation    = locationsRoadWay.Find(a => a.Code == t.FromLocationCode);
                                t.ToLocation      = allLocations.Find(a => a.Code == t.ToLocationCode);
                                t.ToPortEquipment = equipmentsRoadWay.FirstOrDefault(a => a.Code == t.ToPort);
                            });
                            //任务过滤条件,任务port对应的station要可用
                            task1s = task1s.Where(t => availableOutStation.Exists(a => AppSession.ExcuteService.GetOutStationByPort(srm.DestinationArea, t.ToPort, App.WarehouseCode).Data?.Exists(b => b.Code == a.Code) == true)).ToList();

                            //库内取货的任务
                            var task1 = task1s.OrderByDescending(t => t.Priority).ThenBy(t => Math.Abs((int)t.FromLocation.Line - CurrentColumn)).FirstOrDefault();

                            //本巷道接入口的任务
                            var task2s = tempTasks.Where(t => t.TaskStatus == TaskEntityStatus.响应接入站台到达.GetIndexInt() && equipmentsRoadWay.Exists(a => a.Code == t.Gateway)).ToList();
                            task2s.ForEach(t => { t.ArrivaEquipment = equipmentsRoadWay.Find(a => a.Code == t.Gateway); t.ToLocation = allLocations.Find(a => a.Code == t.ToLocationCode); });
                            //按优先级以及站台与现有堆垛机的距离优先做调度
                            var task2 = task2s.OrderByDescending(t => t.Priority).ThenBy(t => Math.Abs(t.ArrivaEquipment.ColumnIndex - CurrentColumn)).FirstOrDefault();
                            if (task1 == null && task2 == null)
                            {
                                //说明当前没有可以被执行的任务
                                return(BllResultFactory.Sucess());
                            }
                            if (task2 != null)
                            {
                                //说明库外取货任务不为空,则下发接入任务
                                //库外取分为换站和其他,换站需要再放到库外,其他则放到库内
                                return(OutGet(srm, plc, availableOutStation, task2));
                            }
                            if (task1 != null)
                            {
                                //说明库内取货任务不为空
                                //库内取分为两种,一种移到库外,一种重新到到库内另一个库位上
                                return(InGet(srm, plc, locationsRoadWay, availableOutStation, task1));
                            }

                            //当两种任务均存在时,此处设置两种模式,出库优先与均衡模式(按堆垛机位置进行)
                            var configResult = AppSession.BllService.GetAllConfig();
                            var config       = configResult.Data?.FirstOrDefault(t => t.Code == ConfigStrings.OutFirst.ToString());
                            if (config == null || config.Value != "1")
                            {
                                //均衡模式
                                var dis1 = Math.Abs((int)task1.FromLocation.Line - CurrentColumn);
                                var dis2 = Math.Abs(task2.ArrivaEquipment.RowIndex1 - CurrentColumn);
                                if (dis1 <= dis2)
                                {
                                    return(InGet(srm, plc, locationsRoadWay, availableOutStation, task1));
                                }
                                else
                                {
                                    return(OutGet(srm, plc, availableOutStation, task2));
                                }
                            }
                            else
                            {
                                //出库优先模式
                                return(OutGet(srm, plc, availableOutStation, task2));
                            }
                        }
                    }

                    else
                    {
                        //hack:其他情况1-库内取货,2-库内放货,3-库外入库,4库外出库, 5重新分配入库地址,暂时不做处理,这里也应不需要处理这些情况
                    }
                }
                //当堆垛机有任务完成且wcs没有任务完成时,说明是堆垛机新发任务完成
                else if (Fork1TaskExecuteStatus == SRMTaskExcuteStatus.任务完成.GetIndexString() && srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.WCSTaskCompleteFlag.ToString()).Value != SSRMTaskCompleteFlag.任务完成.GetIndexString())
                {
                    //todo:检查任务完成
                    //单叉单任务堆垛机只有2种情况会有完成信号  库外出库和库内放货
                    //根据任务号和货叉类型进行任务完成处理
                    int taskNo   = int.Parse(srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.Fork1TaskNo.ToString()).Value);
                    int forkType = int.Parse(srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.Fork1TaskType.ToString()).Value);

                    //库内放货完成
                    if (forkType == SRMForkTaskFlag.库内放货.GetIndexInt())
                    {
                        var task = tasks.FirstOrDefault(t => t.Id == taskNo);
                        if (task != null)
                        {
                            if (!locationsRoadWay.Exists(a => a.Code == task.ToLocationCode))
                            {
                                Logger.Log($"堆垛机{srm.Code},任务:{task.Id},去向库位:{task.ToLocationCode}不在本巷道中", LogLevel.Error);
                                return(BllResultFactory.Error());
                            }
                            var tempStatus = task.TaskStatus;
                            task.TaskStatus = TaskEntityStatus.任务完成.GetIndexInt();
                            task.Updated    = DateTime.Now;
                            task.UpdatedBy  = Accounts.WCS.ToString();
                            var tempResult = AppSession.Dal.UpdateCommonModel <TaskEntity>(task);
                            if (tempResult.Success)
                            {
                                //标记交换区地址,任务完成10
                                var prop = srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.WCSTaskCompleteFlag.ToString());
                                prop.Value = SSRMTaskCompleteFlag.任务完成.GetIndexString();
                                var sendResult = plc.Write(prop);
                                if (sendResult.Success)
                                {
                                    Logger.Log($"堆垛机{srm.Name}完成库内放货成功,任务:{task.Id}", LogLevel.Success);
                                    return(BllResultFactory.Sucess());
                                }
                                else
                                {
                                    //回滚
                                    task.TaskStatus = tempStatus;
                                    AppSession.Dal.UpdateCommonModel <TaskEntity>(task);
                                    Logger.Log($"堆垛机{srm.Name}完成库内放货失败,任务:{task.Id},原因:{sendResult.Msg}", LogLevel.Error);
                                    return(BllResultFactory.Error());
                                }
                            }
                            else
                            {
                                Logger.Log($"完成堆垛机{srm.Name}库内放货失败,任务{task.Id}请求WMS接口失败:{tempResult.Msg}", LogLevel.Error);
                                return(BllResultFactory.Error($"完成堆垛机{srm.Name}库内放货失败,任务{task.Id}请求WMS接口失败:{tempResult.Msg}"));
                            }
                        }
                        else
                        {
                            Logger.Log($"堆垛机{srm.Code}记录任务{task.Id}状态不对,请核查任务是否为本巷道任务,以及任务的状态{Enum.GetName(typeof(TaskEntityStatus), task.TaskStatus)}", LogLevel.Error);
                            return(BllResultFactory.Error());
                        }
                    }
                    //库外放货完成时
                    else if (forkType == SRMForkTaskFlag.库外放货.GetIndexInt())
                    {
                        var task = tasks.FirstOrDefault(t => t.Id == taskNo);
                        if (task != null)
                        {
                            //更新任务状态
                            int preStatus = task.TaskStatus;
                            task.TaskStatus = TaskEntityStatus.响应堆垛机库外放货完成.GetIndexInt();
                            task.Updated    = DateTime.Now;
                            task.UpdatedBy  = Accounts.WCS.ToString();
                            var tempResult = AppSession.Dal.UpdateCommonModel <TaskEntity>(task);
                            if (tempResult.Success)
                            {
                                //标记交换区地址,任务完成10
                                var prop = srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.WCSTaskCompleteFlag.ToString());
                                prop.Value = SSRMTaskCompleteFlag.任务完成.GetIndexString();
                                var sendResult = plc.Write(prop);
                                if (sendResult.Success)
                                {
                                    Logger.Log($"堆垛机{srm.Name}完成库外放货成功,任务:{task.Id}", LogLevel.Success);
                                    return(BllResultFactory.Sucess());
                                }
                                else
                                {
                                    Logger.Log($"堆垛机{srm.Name}完成库外放货失败,任务:{task.Id},原因:{sendResult.Msg}", LogLevel.Error);
                                    task.TaskStatus = preStatus;
                                    AppSession.Dal.UpdateCommonModel <TaskEntity>(task);
                                    return(BllResultFactory.Error());
                                }
                            }
                            else
                            {
                                Logger.Log($"完成堆垛机{srm.Name}库外放货时,更新任务{task.Id}状态失败:{tempResult.Msg}", LogLevel.Error);
                                return(BllResultFactory.Error($"完成堆垛机{srm.Name}库外放货时,更新任务{task.Id}状态失败:{tempResult.Msg}"));
                            }
                        }
                        else
                        {
                            Logger.Log($"堆垛机{srm.Code}记录任务{task.Id}状态不对,请核查任务是否为本巷道任务,以及任务的状态{Enum.GetName(typeof(TaskEntityStatus), task.TaskStatus)}", LogLevel.Error);
                            return(BllResultFactory.Error());
                        }
                    }
                    //未知情况
                    Logger.Log($"堆垛机{srm.Name}的任务完成时候和系统对应的任务出现了异常:PLC:{taskNo}或 货叉的任务类型:{forkType} ", LogLevel.Warning);
                    return(BllResultFactory.Error($"堆垛机{srm.Name}的任务完成时候和系统对应的任务出现了异常:PLC:{taskNo}或 货叉的任务类型:{forkType} "));
                }
                else
                {
                    //Logger.Log($"堆垛机{stocker.Name}的任务完成时候和系统对应的任务出现了异常:PLC:{taskNo}或 货叉的任务类型:{forkType} ", LogLevel.Warning);
                    //未知情况
                    Logger.Log($"堆垛机{srm.Name}处理中,执行状态为:{srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == "Fork1TaskExcuteStatus").Value}", LogLevel.Warning);
                    return(BllResultFactory.Sucess());
                }
            }
            return(BllResultFactory.Sucess());
        }
 /// <summary>
 /// 处理接收到客户端的消息
 /// HACK:目前只返回成功
 /// </summary>
 /// <param name="RecsiveMsg">客户端消息</param>
 /// <returns></returns>
 public static BllResult HandClientRecsiveMsg(string clientRecsiveMsg)
 {
     return(BllResultFactory.Sucess());
 }
Example #5
0
 /// <summary>
 /// 库外取
 /// </summary>
 /// <param name="srm"></param>
 /// <param name="plc"></param>
 /// <param name="availableOutStation"></param>
 /// <param name="task"></param>
 /// <returns></returns>
 private BllResult OutGet(Equipment srm, IPLC plc, List <Equipment> availableOutStation, TaskEntity task)
 {
     if (task.TaskType == TaskType.换站.GetIndexInt())
     {
         //获取目标站台
         var stationsResult = AppSession.ExcuteService.GetOutStationByPort(srm.DestinationArea, task.ToPort, App.WarehouseCode);
         if (!stationsResult.Success)
         {
             Logger.Log($"堆垛机{srm.Code},任务:{task.Id},未找到可出站台:" + stationsResult.Msg, LogLevel.Error);
             return(BllResultFactory.Error(stationsResult.Msg));
         }
         var station = stationsResult.Data.Where(t => availableOutStation.Exists(a => a.Code == t.Code)).OrderBy(t => CurrentColumn - t.ColumnIndex).FirstOrDefault();
         if (station == null)
         {
             Logger.Log($"堆垛机{srm.Name}当前没有可用的站台可以放货,任务:{task.Id}", LogLevel.Warning);
             return(BllResultFactory.Error());
         }
         else
         {
             var tempStatus = task.TaskStatus;
             task.TaskStatus = (int)TaskEntityStatus.发堆垛机换站任务;
             task.Updated    = DateTime.Now;
             task.UpdatedBy  = Accounts.WCS.ToString();
             var result = AppSession.Dal.UpdateCommonModel <TaskEntity>(task);
             if (result.Success)
             {
                 result = SendTaskToSRM(srm, plc, SSRMNewTaskFlag.新任务, SRMForkTaskFlag.库外取货, task.ArrivaEquipment.RowIndex1.ToString(), "0", "0", task.ArrivaEquipment.StationIndex.ToString(), SRMForkTaskFlag.库外放货, station.RowIndex1.ToString(), "0", "0", station.StationIndex.ToString(), task.Id.ToString(), SSRMTaskCompleteFlag.无完成);;
                 if (result.Success)
                 {
                     Logger.Log($"下发堆垛机{srm.Code}换站任务:{task.Id}成功", LogLevel.Success);
                     return(BllResultFactory.Sucess());
                 }
                 else
                 {
                     //回滚
                     task.TaskStatus = tempStatus;
                     AppSession.Dal.UpdateCommonModel <TaskEntity>(task);
                     Logger.Log($"下发堆垛机{srm.Code}换站任务:{task.Id}失败,写入地址失败:{result.Msg}", LogLevel.Error);
                     return(BllResultFactory.Error());
                 }
             }
             else
             {
                 Logger.Log($"下发堆垛机{srm.Code}换站任务时,更新任务{task.Id}状态失败:{result.Msg}", LogLevel.Error);
                 return(BllResultFactory.Error());
             }
         }
     }
     else
     {
         var tempStatus = task.TaskStatus;
         task.TaskStatus = (int)TaskEntityStatus.发堆垛机入库任务;
         task.Updated    = DateTime.Now;
         task.UpdatedBy  = Accounts.WCS.ToString();
         var result = AppSession.Dal.UpdateCommonModel <TaskEntity>(task);
         if (result.Success)
         {
             result = SendTaskToSRM(srm, plc, SSRMNewTaskFlag.新任务, SRMForkTaskFlag.库外取货, task.ArrivaEquipment.RowIndex1.ToString(), "0", "0", task.ArrivaEquipment.StationIndex.ToString(), SRMForkTaskFlag.库内放货, task.ToLocation.RowIndex1.ToString(), task.ToLocation.Line.ToString(), task.ToLocation.Layer.ToString(), "0", task.Id.ToString(), SSRMTaskCompleteFlag.无完成);
             if (result.Success)
             {
                 Logger.Log($"下发堆垛机{srm.Code}入库任务:{task.Id}成功", LogLevel.Success);
                 return(BllResultFactory.Sucess());
             }
             else
             {
                 //回滚
                 task.TaskStatus = tempStatus;
                 AppSession.Dal.UpdateCommonModel <TaskEntity>(task);
                 Logger.Log($"下发堆垛机{srm.Code}入库任务:{task.Id}失败,写入地址失败:{result.Msg}", LogLevel.Error);
                 return(BllResultFactory.Error());
             }
         }
         else
         {
             Logger.Log($"下发堆垛机{srm.Code}入库任务时,更新任务{task.Id}状态失败:{result.Msg}", LogLevel.Error);
             return(BllResultFactory.Error());
         }
     }
 }
        public override BllResult ExcuteRequest(Equipment station, List <Equipment> allEquipments, IPLC plc)
        {
            //获取任务
            var taskResult = AppSession.Dal.GetCommonModelByCondition <TaskEntity>($"where  taskStatus= {TaskEntityStatus.响应堆垛机库外放货完成.GetIndexInt()} " +
                                                                                   $"and gateway = '{station.SelfAddress}' and warehouseCode = '{station.WarehouseCode}'");

            if (taskResult.Success)
            {
                var tasks = taskResult.Data;
                if (tasks.Count == 0)
                {
                    return(BllResultFactory.Error($"站台{station.Name}根据任务状态{TaskEntityStatus.响应堆垛机库外放货完成}没有找到任务数据,请检查数据"));
                }
                if (tasks.Count > 1)
                {
                    return(BllResultFactory.Error($"站台{station.Name}根据任务状态{TaskEntityStatus.响应堆垛机库外放货完成}查找到了多条任务,请检查数据"));
                }
                else
                {
                    var task = taskResult.Data[0];
                    //if (task.Type == TaskType.整盘入库.GetIndexInt() || task.Type == TaskType.空容器入库.GetIndexInt())
                    //{
                    //    Logger.Log($"站台{station.Name}不接受整盘入库和空容器入库任务", LogLevel.Error);
                    //    return;
                    //}
                    if (station.GoAddress.ToString() == "")
                    {
                        return(BllResultFactory.Error($"站台{station.Name}没有设置去向地址"));
                    }

                    int    tempStatus  = task.TaskStatus; //记录原始状态以便回滚
                    string tempGateWay = task.Gateway;

                    task.TaskStatus = TaskEntityStatus.响应接出口站台请求.GetIndexInt();
                    task.Gateway    = station.Code;
                    //task.Roadway = station.RoadWay;
                    var temp = AppSession.Dal.UpdateCommonModel <TaskEntity>(task);
                    if (temp.Success)
                    {
                        String number = station.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == "RequestNumber").Value;
                        String weight = station.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == "RequestWeight").Value;
                        String length = station.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == "RequestLength").Value;
                        String width  = station.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == "RequestWidth").Value;
                        String height = station.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == "RequestHeight").Value;
                        temp = SendAddressReplyToPlc(station, plc, StationMessageFlag.地址回复, StationLoadStatus.回复到达,
                                                     number, task.ContainerCode, weight, length, width, height, station.GoAddress.ToString(), "");
                        if (temp.Success)
                        {
                            return(BllResultFactory.Sucess($"响应站台{station.Name}地址请求成功,条码{task.ContainerCode},任务{task.Id}"));
                        }
                        else
                        {
                            task.TaskStatus = tempStatus;
                            task.Gateway    = tempGateWay;
                            AppSession.Dal.UpdateCommonModel <TaskEntity>(task);
                            return(BllResultFactory.Error($"响应站台{station.Name}地址请求失败,条码{task.ContainerCode},任务{task.Id},回滚任务状态"));
                        }
                    }
                    else
                    {
                        return(BllResultFactory.Error($"站台{station.Name},响应请求时更新任务{task.Id}状态失败。"));
                    }
                }
            }
            else
            {
                return(BllResultFactory.Error($"站台{station.Name}未能获取到任务状态为'{TaskEntityStatus.响应堆垛机库外放货完成}'的任务,请检查数据。"));
            }
        }
Example #7
0
        public override BllResult ExcuteArrive(Equipment station, List <Equipment> allEquipments, IPLC plc)
        {
            var isSuccess = station.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == StationProps.ArriveResult.ToString()).Value;

            if (isSuccess == StationArriveResult.成功.GetIndexString())
            {
                //获取条码
                var barcode = station.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == StationProps.ArriveBarcode.ToString()).Value;
                if (string.IsNullOrWhiteSpace(barcode))
                {
                    return(BllResultFactory.Error($"站台{station.Name}有位置到达但是没有条码信息"));
                }
                else
                {
                    var taskResult = AppSession.Dal.GetCommonModelByCondition <TaskEntity>($"where containerCode = '{barcode}' and taskStatus < {TaskEntityStatus.任务完成.GetIndexInt()} and deleted = 0");
                    if (taskResult.Success)
                    {
                        if (taskResult.Data.Count > 1)
                        {
                            return(BllResultFactory.Error($"站台{station.Name}根据条码{barcode}查找到了多条任务,请检查数据"));
                        }
                        else
                        {
                            var task = taskResult.Data[0];
                            if (task.TaskType == TaskType.空容器出库.GetIndexInt() || task.TaskType == TaskType.整盘出库.GetIndexInt() || task.TaskType == TaskType.换站.GetIndexInt())
                            {
                                using (IDbConnection connection = AppSession.Dal.GetConnection())
                                {
                                    IDbTransaction transaction = null;
                                    try
                                    {
                                        connection.Open();
                                        transaction = connection.BeginTransaction();
                                        var result = AppSession.TaskService.CompleteTask(task.Id.Value, App.User.UserCode, connection, transaction);
                                        if (result.Success)
                                        {
                                            //回复位置到达
                                            result = SendAckToPlc(station, plc, StationMessageFlag.WCSPLCACK, StationLoadStatus.回复到达, station.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == StationProps.ArriveRealAddress.ToString()).Value, "0");
                                            if (result.Success)
                                            {
                                                transaction.Commit();
                                                //发送LED
                                                AppSession.BllService.SendLED(station, task);
                                                return(BllResultFactory.Sucess($"响应站台{station.Name}位置到达成功,完成任务成功,条码{barcode},任务{task.Id}"));
                                            }
                                            else
                                            {
                                                transaction.Rollback();
                                                return(BllResultFactory.Error($"响应站台{station.Name}位置到达失败,条码{barcode},任务{task.Id},详情:{result.Msg}"));
                                            }
                                        }
                                        else
                                        {
                                            transaction.Rollback();
                                            return(BllResultFactory.Error($"响应站台{station.Name}位置到达请求失败,完成任务失败,条码{barcode},任务{task.Id},详情:{result.Msg}"));
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        transaction?.Rollback();
                                        return(BllResultFactory.Error($"响应站台{station.Name}位置到达请求失败,完成任务失败,条码{barcode},任务{task.Id},详情:{ex.Message}"));
                                    }
                                }
                            }
                            else
                            {
                                return(BllResultFactory.Error($"响应站台{station.Name}位置到达请求失败,完成任务失败,条码{barcode},任务{task.Id},详情:只出站台对应的任务类型有问题"));
                            }
                        }
                    }
                    else
                    {
                        return(BllResultFactory.Error($"站台{station.Name}根据条码{barcode}没有查询到任务:{taskResult.Msg}"));
                    }
                }
            }
            else
            {
                return(BllResultFactory.Error($"站台{station.Name}位置到达失败"));
            }
        }
        /// <summary>
        /// 具体的站台实现逻辑
        /// </summary>
        /// <param name="stations"></param>
        /// <param name="plcs"></param>
        /// <returns></returns>
        public override void Excute(List <Equipment> stations, List <Equipment> allEquipments, IPLC plc)
        {
            //每隔3秒处理一次到达和离开
            if (DateTime.Now.Subtract(excuteDateTime).Seconds > 3)
            {
                excuteDateTime = DateTime.Now;
            }
            else
            {
                return;
            }
            var locations = AppSession.Dal.GetCommonModelByCondition <ProductFinishedStation>($"where 1=1");

            if (locations.Success)
            {
                foreach (var station in stations)
                {
                    BllResult result = null;
                    try
                    {
                        var location = locations.Data.FirstOrDefault(t => t.Code == station.Code);
                        if (station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypeTemplateCode == StationProps.AGV_Arrive_WCS.ToString())?.Value == true.ToString())
                        {
                            //如果AGV到达,并且库位是停用的,就改为可以用
                            if (location.IsStop == true)
                            {
                                location.IsStop = false;
                                AppSession.Dal.UpdateCommonModel <ProductFinishedStation>(location);
                                result = BllResultFactory.Sucess($"AGV站台[{station.Code}][{station.Name}]到达,对应的库位{location.Code}更改为可用");
                            }
                        }
                        if (station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypeTemplateCode == StationProps.AGV_Leave_WCS.ToString())?.Value == true.ToString())
                        {
                            //如果AGV不是到达,并且库位未锁定,就改为停用,恢复为1层1列
                            if (location.IsStop == false)
                            {
                                var stepTraceResult = AppSession.Dal.GetCommonModelByCondition <StepTrace>($"where status < {StepTraceStatus.下发放货任务.GetIndexInt()} and nextStationId = '{station.StationId}'");
                                if (stepTraceResult.Success)
                                {
                                    foreach (var stepTrace in stepTraceResult.Data.Where(t => t.Status < StepTraceStatus.发取货任务.GetIndexInt()))
                                    {
                                        stepTrace.NextStationId = 0;
                                        stepTrace.WCSLayer      = null;
                                        stepTrace.WCSLine       = null;
                                        stepTrace.Status        = StepTraceStatus.设备请求下料.GetIndexInt();
                                        AppSession.Dal.UpdateCommonModel <StepTrace>(stepTrace);
                                    }
                                    foreach (var stepTrace in stepTraceResult.Data.Where(t => t.Status == StepTraceStatus.发取货任务.GetIndexInt()))
                                    {
                                        var stationCode = string.Empty;

                                        switch (station.Code)
                                        {
                                        case "StationForFinished1":
                                            stationCode = "StationForFinished2";
                                            break;

                                        case "StationForFinished2":
                                            stationCode = "StationForFinished1";
                                            break;

                                        case "StationForFinished3":
                                            stationCode = "StationForFinished4";
                                            break;

                                        case "StationForFinished4":
                                            stationCode = "StationForFinished3";
                                            break;
                                        }
                                        var otherStation = stations.Find(t => t.Code == stationCode);
                                        if (otherStation != null)
                                        {
                                            List <Station>    stationList        = station.StationList.Where(t => t.Id == otherStation.StationId).ToList();
                                            TrussNormalExcute trussNormalExcutea = new TrussNormalExcute();
                                            trussNormalExcutea.setStation(stationList, stepTrace, stepTrace.NextStepId.Value);
                                        }
                                    }
                                }
                                location.PutType = (int)PutTypeFlag.初始摆放类型值;
                                location.Line    = 1;
                                location.Layer   = 1;
                                location.IsStop  = true;
                                AppSession.Dal.UpdateCommonModel <ProductFinishedStation>(location);
                                result = BllResultFactory.Sucess($"AGV站台[{station.Code}][{station.Name}]离开,对应的库位{location.Code}更改为停用,并且恢复到1列1层");
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        result = BllResultFactory.Error($"AGV站台[{station.Code}][{station.Name}]处理发生异常:{ex.Message}");
                    }
                    LogResult(result);
                }
            }
        }
Example #9
0
        public override BllResult ExcuteRequest(Equipment station, List <Equipment> allEquipments, IPLC plc)
        {
            var    barcode       = station.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == StationProps.RequestBarcode.ToString()).Value;
            var    requestNumber = station.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == StationProps.RequestNumber.ToString()).Value;
            var    height        = station.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == StationProps.RequestHeight.ToString()).Value;
            var    weight        = station.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == StationProps.RequestWeight.ToString()).Value;
            var    length        = station.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == StationProps.RequestLength.ToString()).Value;
            var    width         = station.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == StationProps.RequestWidth.ToString()).Value;
            string goAddress     = "";
            string backAddress   = "";

            if (string.IsNullOrWhiteSpace(barcode))
            {
                SendBack(station, plc, barcode);
                return(BllResultFactory.Error($"站台{station.Name}有地址请求但是没有条码信息"));
            }
            else
            {
                //获取任务
                var taskResult = AppSession.Dal.GetCommonModelByConditionWithZero <TaskEntity>($"where containerCode = '{barcode}' and taskStatus < {TaskEntityStatus.任务完成.GetIndexInt()} and deleted = 0");
                if (taskResult.Success)
                {
                    if (taskResult.Data.Count > 1)
                    {
                        SendBack(station, plc, barcode);
                        return(BllResultFactory.Error($"站台{station.Name}根据条码{barcode}查找到了多条任务,请检查数据"));
                    }
                    if (taskResult.Data.Count == 0)
                    {
                        return(BllResultFactory.Error($"站台{station.Name}根据条码{barcode}没有找到任务,请检查数据"));
                    }
                    else
                    {
                        var task = taskResult.Data[0];
                        if (task.TaskType == TaskType.整盘出库.GetIndexInt() || task.TaskType == TaskType.空容器出库.GetIndexInt())
                        {
                            SendBack(station, plc, barcode);
                            return(BllResultFactory.Error($"站台{station.Name}不接受整盘出库和空托盘出库任务"));
                        }
                        //检测是否有去向库位,没有则请求
                        if (task.TaskType == TaskType.换站.GetIndexInt())
                        {
                            //如果是换站任务,则port不能为此站台,否则无意义
                            if (task.ToPort == station.Code)
                            {
                                SendBack(station, plc, barcode);
                                return(BllResultFactory.Error($"托盘{task.ContainerCode}为换站任务,但是换站目的地与入口目的地相同"));
                            }
                        }
                        goAddress = station.GoAddress;
                        if (string.IsNullOrWhiteSpace(goAddress))
                        {
                            // 检测是否有去向库位或去向站台   设计逻辑:优先考虑是否分配了目标区域,没有则判断是否分配了库位
                            if (string.IsNullOrWhiteSpace(task.DestinationArea))
                            {
                                if (string.IsNullOrWhiteSpace(task.ToLocationCode))
                                {
                                    //没有分配目标区域,也没有分配库位的情况  这个时候需要请求上游系统分配目标区域或库位
                                    //hack:这里默认进行去向库位获取,按需改成获取去向区域
                                    LocationAssignReqModelInfo locationRequest = new LocationAssignReqModelInfo();
                                    locationRequest.TaskNo = task.RemoteTaskNo.ToString();
                                    locationRequest.Height = height;
                                    locationRequest.Weight = weight;
                                    locationRequest.Length = length;
                                    locationRequest.Width  = width;
                                    var result = AppSession.TaskService.GetDestinationLocationFromWMS(locationRequest);
                                    if (!result.Success)
                                    {
                                        SendBack(station, plc, barcode);
                                        return(BllResultFactory.Error($"任务{task.Id}没有去向库位,并且请求上游系统库位失败:{result.Msg}"));
                                    }
                                    Logger.Log($"任务{task.Id}请求上位系统去向库位成功,获取库位为:{result.Data.Code}", LogLevel.Success);
                                    task.DestinationArea = result.Data.DestinationArea;
                                    task.ToLocationCode  = result.Data.Code;
                                }
                                else
                                {
                                    //没有分配目标区域,分配了库位的情况
                                    // 根据库位 查找巷道
                                    var temp2 = AppSession.LocationService.GetLocationByCode(task.ToLocationCode);
                                    if (!temp2.Success)
                                    {
                                        SendBack(station, plc, barcode);
                                        return(BllResultFactory.Error($"任务{task.Id}获取去向库位{task.ToLocationCode}出错:{temp2.Msg}"));
                                    }
                                    task.DestinationArea = temp2.Data.DestinationArea;
                                }
                                //将获取到的数据进行update
                                AppSession.Dal.UpdateCommonModel <TaskEntity>(task);
                            }
                            //根据目标区域查找前进地址
                            var temp3 = AppSession.ExcuteService.GetGoAddressByDestinationArea(task.DestinationArea, station.Code, App.WarehouseCode);
                            if (!temp3.Success)
                            {
                                SendBack(station, plc, barcode);
                                return(BllResultFactory.Error($"托盘{task.ContainerCode}没有查找到对应请进地址,请核对信息是否录入维护错误"));
                            }
                            //hack:这里默认取第一个,如果有项目存在多个选择,请加逻辑进行判断
                            if (string.IsNullOrWhiteSpace(temp3.Data[0].SelfAddress))
                            {
                                SendBack(station, plc, barcode);
                                return(BllResultFactory.Error($"托盘{task.ContainerCode}查找设备{temp3.Data[0].Code}无目标地址,请核对设备信息是否配置正确"));
                            }
                            goAddress = temp3.Data[0].SelfAddress;
                        }

                        int    tempStatus = task.TaskStatus; //记录原始状态以便回滚
                        string tempArrivaEquipmentCode = task.Gateway;
                        task.TaskStatus = TaskEntityStatus.拣选台回库.GetIndexInt();
                        task.Gateway    = station.Code;
                        task.ReqHeight  = height;
                        task.ReqLength  = length;
                        task.ReqWeight  = weight;
                        task.ReqWidth   = width;
                        var temp = AppSession.Dal.UpdateCommonModel <TaskEntity>(task);
                        if (temp.Success)
                        {
                            //回复地址请求
                            temp = SendAddressReplyToPlc(station, plc, StationMessageFlag.地址回复, StationLoadStatus.默认,
                                                         requestNumber, barcode, weight, length, width, height, goAddress, backAddress);
                            if (temp.Success)
                            {
                                //发送LED
                                AppSession.BllService.SendLED(station, task);
                                return(BllResultFactory.Sucess($"响应站台{station.Name}地址请求成功,条码{barcode},任务{task.Id}"));
                            }
                            else
                            {
                                task.TaskStatus = tempStatus;
                                task.Gateway    = tempArrivaEquipmentCode;
                                AppSession.Dal.UpdateCommonModel <TaskEntity>(task);
                                SendBack(station, plc, barcode);
                                return(BllResultFactory.Error($"响应站台{station.Name}地址请求失败,条码{barcode},任务{task.Id},详情:{temp.Msg},回滚任务状态"));
                            }
                        }
                        else
                        {
                            SendBack(station, plc, barcode);
                            return(BllResultFactory.Error($"站台{station.Name},响应请求时更新任务{task.Id}状态失败。详情:{temp.Msg}"));
                        }
                    }
                }
                else
                {
                    SendBack(station, plc, barcode);
                    return(BllResultFactory.Error($"站台{station.Name}根据条码{barcode}没有查询到任务:{taskResult.Msg}"));
                }
            }
        }