...
杨前锦
2025-06-11 10e84968f9c70ebf6c83893091a36863b1e27b2a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
using HH.WCS.Mobox3.FJJF.models;
using HH.WCS.Mobox3.FJJT.api;
using HH.WCS.Mobox3.FJJT.device;
using HH.WCS.Mobox3.FJJT.dispatch;
using HH.WCS.Mobox3.FJJT.process;
using HH.WCS.Mobox3.FJJT.wms;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using static HH.WCS.Mobox3.FJJT.api.ApiHelper;
using static HH.WCS.Mobox3.FJJT.api.ApiModel;
using HH.WCS.Mobox3.FJJT.util;
 
namespace HH.WCS.Mobox3.FJJT.core {
    internal class WCSCore {
 
        /// <summary>
        /// AGV任务回报
        /// 1.根据回报AGV任务状态,更新货位信息和任务状态
        /// 2.判断WMSTask是否是出库任务,是,如果工装内有物料,则判断物料是否合格,不合格,则生成不合格品入库任务
        /// 3.如果合格,则触发余料/空托回库任务
        /// </summary>
        /// <param name="model"></param>
        public static void OperateAgvTaskStatus(AgvTaskState model) {
            try
            {
                if (string.IsNullOrEmpty(model.No))
                {
                    //无任务号请求(交管)
                    //DeviceProcess.Traffic(model.ForkliftNo, model.LockNo, model.State==1023);
                }
                else
                {
                    var cst = WCSHelper.GetTask(model.No);
 
                    if (cst != null)
                    {
                        var mst = WMSHelper.GetWmsTask(cst.S_OP_CODE);
                        if (mst != null)
                        {
                            WCSHelper.AddActionRecord(model.No, model.State, model.ForkliftNo, model.ExtData);
                            if (model.State <= 7)
                            {
                                //有任务号请求
                                switch (model.State)
                                {
                                    case 1:
                                        WCSHelper.Begin(cst);
                                        WMSHelper.updateMesTaskStatus(mst.S_CODE, "2");  // 更新MES任务状态
                                        break;
                                    #region MyRegion
                                    case 3:
                                        WCSHelper.UpdateStatus(cst, "开始取货");
                                        var locCntrRels = LocationHelper.GetLocCntr(cst.S_START_LOC);
                                        if (locCntrRels.Count > 0) 
                                        {
                                            cst.S_CNTR_CODE = locCntrRels[0].S_CNTR_CODE;
                                            WCSHelper.UpdateWcsTask(cst);
                                        }
                                        break;
                                    case 4:
                                        WCSHelper.UpdateStatus(cst, "取货完成");
                                        LocationHelper.UnLockLoc(cst.S_START_LOC);
                                        TaskProcess.OperateStatus(cst, 4);
                                        break;
                                    case 5:
                                        WCSHelper.UpdateStatus(cst, "开始卸货");
                                        break;
                                    case 6:
                                        WCSHelper.UpdateStatus(cst, "卸货完成");
                                        LocationHelper.UnLockLoc(cst.S_END_LOC);
                                        TaskProcess.OperateStatus(cst, 6);
                                        break;
                                    #endregion
                                    case 2:
                                        WCSHelper.End(cst);
                                        break;
                                    case 7:
                                        TaskProcess.OperateStatus(cst, 7);
                                        WCSHelper.Fail(cst);
                                        break;
                                }
                            }
                            else if (model.State == 1012)
                            {
                                LogHelper.Info("开始进行RFID扫描", "AGV");
                                ContainerHelper.UpdateCntrState(cst.S_CNTR_CODE, 1);
                                WMSHelper.addRfidAnomalyRecord(cst.S_CNTR_CODE, 2, cst.S_START_LOC, null);
                                // 查询扫描的RFID
                                // 发送 00 04 71 02到扫码器 ,接受返回数据并解析
                                byte[] bytes = new byte[] { 00, 04, 71, 02 };
                                var plc = Settings.carDeviceInfos.Where(a => a.deviceNo == model.ForkliftNo && a.enable == 1).FirstOrDefault();
                                TcpServer.TcpServerSend(plc.address, bytes);
                            }
                            else if (model.State == 1002)
                            {
                                LogHelper.Info("开始获取AGV终点", "AGV");
                                // 更新AGV终点
                                // 判断容器是否异常,修改1002的终点参数 ,并将参数6修改为1
                                Container container = ContainerHelper.GetCntr(cst.S_CNTR_CODE);
                                if (container != null)
                                {
                                    LogHelper.Info($"容器的异常状态为:{container.N_E_STATE}", "AGV");
                                    string agvEndLoc = null;
                                    if (container.N_E_STATE == 0)
                                    {
                                        agvEndLoc = ApiHelper.AGVApplyDest(model.No, cst.S_START_LOC, cst.S_CNTR_CODE, "1");
                                    }
                                    else
                                    {
                                        agvEndLoc = ApiHelper.AGVApplyDest(model.No, cst.S_START_LOC, cst.S_CNTR_CODE, "2");
                                    }
 
                                    ChangeParamModel paramModel = new ChangeParamModel() 
                                    {
                                        task_no = model.No,
                                        param_no = 0,
                                        param = $"{model.No};{cst.S_START_LOC};{cst.S_END_LOC};4;512;0;1"
                                    };
                                    NDCApi.ChangeOrderParam(paramModel);
                                    LogHelper.Info($"变更AGV终点:{agvEndLoc}", "AGV");
                                }
                                else
                                {
                                    WMSHelper.addAlarmRecord("流程异常", "中", $"AGV任务回报,任务容器编码:{cst.S_CNTR_CODE}的容器没有录入到WMS系统","AGV");
                                }
                            }
                            else
                            {
                                //安全请求等
                                TaskProcess.OperateReq(model.No, model.State, model.ForkliftNo, model.ExtData);
                            }
 
                            // AGV任务完成
                            if (model.State == 2)
                            {
                                // 检测物料是否合格,如不合格,
                                // 判断物料是否是环带库物料,是则回环带库,并让环带下发新的物料
                                // 非环带库物料,则退出立库,同时下发新的物料出库任务
                                if (cst.S_TYPE.Contains("叫料出库任务"))
                                {
                                    var cntrItemRels = ContainerHelper.GetCntrItemRel(cst.S_CNTR_CODE);
                                    if (cntrItemRels != null && cntrItemRels.Count > 0)
                                    {
                                        if (cntrItemRels[0].S_ITEM_STATE == "2")
                                        {
                                            // 不合格品回库
                                            ApiHelper.rejectReturnStock(mst, cst);
                                        }
                                    }
                                }
 
                                // 检测是否是读码位,非读码位,可以激活预创建任务
                                var transfe = WMSHelper.GetTransfeRelevance(cst.S_END_LOC);  // 接驳位属性
                                if (transfe != null && transfe.N_READ_LOC == 1) 
                                {
                                    WCSHelper.ActivatePreCreateTask(mst.S_CODE);
                                }
                                else if ( transfe.N_READ_LOC == 0)
                                {
                                    if (cst.S_TYPE.Contains("【异常】"))
                                    {
                                        WCSHelper.ActivatePreCreateTask(mst.S_CODE,1);
                                    }
                                    else 
                                    {
                                        WCSHelper.ActivatePreCreateTask(mst.S_CODE);
                                    }
                                }
 
                                // 查询是否有未完成的任务
                                if (WMSHelper.isFinishTask(mst.S_CODE))
                                {
                                    // 更新作业任务状态
                                    mst.N_B_STATE = 2;
                                    mst.T_END_TIME = DateTime.Now;
                                    WMSHelper.UpdateTaskState(mst);
 
                                    // 更新任务中间表状态
                                    WMSHelper.updateMesTaskStatus(mst.S_CODE, "3");
 
                                    // 如果作业名称为成型机叫料出库任务,则触发余料/空托搬运任务
                                    string locCode = WMSHelper.getReturnMaterialLocCode(mst.S_END_LOC);
                                    ApiHelper.returnMaterialOrEmptyTray(locCode);
                                }   
                            }
                        }
                        else
                        {
                            WMSHelper.addAlarmRecord("系统错误", "高", $"AGV任务状态回报,作业号:{cst.S_OP_CODE},未查询到作业","AGV");
                        }
                    }
                    else
                    {
                        WMSHelper.addAlarmRecord("系统错误", "高", $"AGV任务状态回报,任务号:{model.No},未查询到任务","AGV");
                    }
                }
            }
            catch (Exception ex) 
            {
                WMSHelper.addAlarmRecord("系统错误","高", $"WMS内部错误:agv任务状态回报错误,错误原因:{ex.Message}","AGV");
            }
        }
 
        /// <summary>
        /// 任务分发,根据调度类型发给不同的调度系统
        /// </summary>
        internal static void Dispatch() {
            //查询任务
            //获取所有等待的任务
            var list = WCSHelper.GetWaitingTaskList();
            if (list.Count > 0) {
                list.ForEach(task => {
 
                    if (!TaskProcess.Intercept(task)) {
                        //使用自定义任务推送
                        TaskProcess.SendTask(task);
                    }
 
                });
 
 
            }
        }
 
        /// <summary>
        /// 杭奥堆垛机信号反馈
        /// </summary>
        /// <param name="model"></param>
        internal static void OperateHATaskStatus(HanAo.TaskStateInfoModel model) {
            var wcsTask = WCSHelper.GetTask(model.requestPk);
            if (wcsTask != null) {
                if (model.code == "0") {
                    //
                    if (wcsTask.S_TYPE == "堆垛机入库") {
                        //终点托盘绑定
                        if (LocationHelper.BindingLoc(wcsTask.S_END_LOC, new List<string> { wcsTask.S_CNTR_CODE })) {
                            //修改托盘状态为可用,增加库存量表,后面分拣出可以计算到
                            
 
                        }
                    }
                    else if (wcsTask.S_TYPE == "堆垛机出库") {
                        //起点托盘解绑
                        LocationHelper.UnBindingLoc(wcsTask.S_START_LOC, new List<string> { wcsTask.S_CNTR_CODE });
                    }
                    //标记任务完成
                    //标记作业完成
                    wcsTask.N_B_STATE = 3;
                    WCSHelper.UpdateStatus(wcsTask);
                    var wmsTask = WMSHelper.GetWmsTask(wcsTask.S_OP_CODE);
                    if (wmsTask != null) {
                        wmsTask.N_B_STATE = 2;
                        WMSHelper.UpdateTaskState(wmsTask);
                    }
                }
            }
        }
    }
}