ams
cjs
2025-05-28 1fb5bbbd57fcc62e5dfb38a058a0aeca0118d643
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
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
using Hanhe.iWCS.Business;
using Hanhe.iWCS.Common;
using Hanhe.iWCS.Interface;
using Hanhe.iWCS.MData;
using Hanhe.iWCS.Model;
using Hanhe.iWCS.Model.AMS;
using Microsoft.Owin.Hosting;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using static Hanhe.iWCS.IndonesiaGLMProtocol.EnentListen;
using static Hanhe.iWCS.IndonesiaGLMProtocol.MESHelper;
using static Hanhe.iWCS.IndonesiaGLMProtocol.ProcessHelper;
using static Hanhe.iWCS.IndonesiaGLMProtocol.PLCControl;
using MongoDB.Bson;
using static Hanhe.iWCS.IndonesiaGLMProtocol.ERPService;
 
namespace Hanhe.iWCS.IndonesiaGLMProtocol
{
    /// <summary>
    /// 设备协议解析类
    /// </summary>
    public class ProtocolAnalysis : IProtocolAnalysis
    {
        private EquipmentCommandEQBLL CommandEQBLL = new EquipmentCommandEQBLL();
        private ICallTaskProcessing iCallTask = new ICallTaskProcessing();
        private Logger AMSLoggerAPI = new Logger();
 
        public void StringRequestInfo(string protocolMsg, string address, int port) {
        }
 
        public void StringRequestInfo(string protocolMsg, string address, int port, string sessionID) {
            //16进制接收
            protocolMsg = protocolMsg.Trim();//3f 00 11 20 30 40 50 60 70 80 90 A0 24 24
            if (protocolMsg != "") {
            }
            #region 握手反馈指令
            //UpdateHandshakeFeedbackCode(protocolMsg);
            PLCControl.Analysis(protocolMsg);
 
            #endregion
        }
        
        public void UpdateHandshakeFeedbackCode(string commandText) {
            var query = Query.And(Query.EQ("CommandText", commandText + "$$"), Query.EQ("Status", Constants.COMMANDEQ_STATUS_SENDED));
            EquipmentCommandEQ eq = MongoDBSingleton.Instance.FindOne<EquipmentCommandEQ>(query, typeof(EquipmentCommandEQ).Name);
            if (eq != null) {
                UpdateBuilder updateBuider = Update.Set("isHandshake", 1).Set("FeedbackCode", commandText);
                MongoDBSingleton.Instance.Update<EquipmentCommandEQ>(query, updateBuider, UpdateFlags.None);
            }
        }
 
        private static bool api = false;
        public ProtocolAnalysis() {
            if (!api) {
                Startup();
                api = true;
            }
        }
        public static void Startup() {
            //Console.WriteLine("Startup ApiController");
            Task.Run(() => {
                var url = "http://+:8801";
                using (WebApp.Start<Startup>(url)) {
                    //Console.WriteLine("Running on {0}", url);
                    Console.ReadLine();
                }
            });
        }
 
        public int workflowToDeviceDriver(TN_I_TASK_DTL_ACTION action) {
            int iResult = 0;
            CMMLog.Info($"任务处理:Action Code:{action.CN_N_ACTION_CODE},TaskNo:{action.CN_S_TASK_NO}");
            
            switch (action.CN_N_ACTION_CODE)
            {
                case 1012: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "起点申请进入"); break;
                case 1312: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "电梯安全对接"); break;
                case 1112: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "滚筒车起点到位"); break;
                case 1212: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "滚筒车取货完成通知PLC"); break;
                case 1013: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "终点申请进入"); break;
                case 1113: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "滚筒车终点到位"); break;
                case 1213: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "滚筒车卸货完成通知PLC"); break;
                case 1313: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "拍照扫码"); break;
            }
 
            if (action.CN_N_ACTION_CODE == 1027) {
                var mst = iCallTask.FindTask(action.CN_S_TASK_NO);
                if (mst != null ) {
                    if (ProcessHelper.Intercept(mst))
                    {
                        iResult = 1027;//拦截更改 WCS 任务类型(将 WMS 任务类型更改为 WCS 任务类型,因为 WCS 需要根据任务类型进行对应任务流程处理)
                        iCallTask.UpdateTask(mst.CN_S_TASK_NO, "未执行");
                    }
                    else
                    {
                        CMMLog.Info($"推送任务:任务号{mst.CN_S_TASK_NO},任务类型:{mst.CN_S_BUSS_TYPE}");
                        ProcessHelper.SendTask(mst);
                    }
                }
                iResult = 1027;
            }
 
            #region 取消
            if (action.CN_N_ACTION_CODE == 7) {
                TN_I_TASK_MST mst = iCallTask.FindTask(action.CN_S_TASK_NO);
                CMMLog.Info(JsonConvert.SerializeObject(mst));
                string agvNo = action.CN_S_DEVICE_CODE;
                if (mst != null)
                {
                    CMMLog.Info($"type:{agvNo}");
                    mst.CN_S_BUSS_TYPE = getTaskType(mst.CN_S_BUSS_TYPE, false);
                    CMMLog.Info($"type:{mst.CN_S_BUSS_TYPE}");
                    CMMLog.Info("action.CN_N_ORDER:"+ action.CN_N_ORDER);
                    //请求前
                    if (action.CN_N_ORDER == 0)
                        WorkFlowAction.TrackLog(action.CN_S_TASK_NO, 0, 7, "收到ams取消请求");
 
                    if (action.CN_N_ORDER == 1 || action.CN_N_ORDER == 0) {
                        ProcessHelper.TaskCancel(mst);
                        iCallTask.CancelTask(mst.CN_S_TASK_NO, "1");
                        AMSHelper.SetStatus(action.CN_S_TASK_NO, 1, "7", "0", true);
                        if (mst.CN_S_BUSS_TYPE != "电梯取货" && mst.CN_S_BUSS_TYPE != "电梯卸货" && mst.CN_S_BUSS_TYPE != "3楼包装取料") 
                            WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE);
                        iCallTask.DeleteTask(mst.CN_S_TASK_NO);
                    }
                    if (mst.CN_S_BUSS_TYPE == "电梯取货" || mst.CN_S_BUSS_TYPE == "电梯卸货" || mst.CN_S_BUSS_TYPE == "满托入库" || mst.CN_S_BUSS_TYPE == "空托出库")
                    {
                        ProcessHelper.ForceCancel(mst, action);
                        MongoDBSingleton.Instance.Remove<TimeCuoInfoCom>(Query.EQ("timeStamp",mst.CN_S_BATCH_NO),RemoveFlags.None);
                    }
                    if (mst.CN_S_START_BIT.Contains("TSJ") || mst.CN_S_END_BIT.Contains("TSJ"))
                    {
                        MongoDBSingleton.Instance.Remove<elevatorTask>(Query.EQ("S_USE", "0"), RemoveFlags.None);
                    }
                    //if (mst.CN_S_BUSS_TYPE == "包装线补空") PLCControl.PickUpBlankComplete(mst.CN_S_END_BIT);
                }
            }
 
            #endregion
 
            #region 强制完成
            if (action.CN_N_ACTION_CODE == 1022) {
                TN_I_TASK_MST mst = iCallTask.FindTask(action.CN_S_TASK_NO);
                if (mst != null)
                {
                    mst.CN_S_BUSS_TYPE = getTaskType(mst.CN_S_BUSS_TYPE, false);
                    ProcessHelper.ForceComplete(mst, action);
                    if (mst.CN_S_BUSS_TYPE == "3楼缓存架入叠托")
                    {
                        var plc = Settings.GetPlcInfo().Where(a => a.deviceType == "3").FirstOrDefault();
                        if (plc != null)
                        {
                            var machine = MongoDBSingleton.Instance.FindOne<WMSInfo>(Query.EQ("trayCode", mst.CN_S_BATCH_NO), "WMSInfo");
                            if (machine != null)
                            {
                                #region   写多个MODBUS数据
                                int[] num = DiePan(machine);
 
                                CMMLog.Info($"send num:" +JsonConvert.SerializeObject(num));
                                var wirteall01 = OITcpHelper.RegisterWriteOutPutMulti(new OITcpHelper.RegisterWriteOutPutModelMulti
                                {
                                    addr = plc.writeAddr + 10,
                                    host = plc.ip,
                                    port = plc.port,
                                    data = num
                                });
                                #endregion
                                MongoDBSingleton.Instance.Remove<WMSInfo>(Query.EQ("trayCode", mst.CN_S_BATCH_NO), "WMSInfo", RemoveFlags.Single);
                            }
                        }
                    }
                    MongoDBSingleton.Instance.Remove<Mongo_AGV_TASK_STATE>(Query.EQ("TaskNo", mst.CN_S_TASK_NO), RemoveFlags.Single);
                    WorkFlowAction.TrackLog(mst.CN_S_TASK_NO, 1, 1022, "收到ams强制完成请求");
                    AMSHelper.SetStatus(action.CN_S_TASK_NO, 1, "1022", "0", true);
                    iCallTask.CancelTask(mst.CN_S_TASK_NO, "1");
                    if (mst.CN_S_BUSS_TYPE != "电梯取货" && mst.CN_S_BUSS_TYPE != "电梯卸货" && mst.CN_S_BUSS_TYPE != "3楼包装取料" && mst.CN_S_BUSS_TYPE != "包装间提升机") 
                        WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE);
                    if (mst.CN_S_BUSS_TYPE == "电梯取货" && mst.CN_S_BUSS_TYPE == "电梯卸货") 
                        MongoDBSingleton.Instance.ReomveAll<TimeCuoInfoCom>();
                    if (mst.CN_S_BUSS_TYPE == "包装线补空") PLCControl.PickUpBlankComplete(mst.CN_S_END_BIT);
                    if (mst.CN_S_BUSS_TYPE == "3楼复称入缓存架" || mst.CN_S_BUSS_TYPE == "3楼复称入缓存架NG") 
                    {
                        var plc = Settings.GetPlcInfo().Where(a => a.location == mst.CN_S_START_BIT && a.enable == 1).FirstOrDefault();
                        if (plc != null)
                        {
                            PLCControl.SecondWeightInCache4(plc.ip, mst.CN_S_TASK_NO);
                        }
                        
                    }
                    if (mst.CN_S_END_BIT.Contains("TSJ"))
                    {
                        ProcessHelper.createDTTask();
                    }
                    if (mst.CN_S_BUSS_TYPE == "3楼包装取料")
                    {
                        //判断是否是复秤入缓存架任务
                        var plcInfo = Settings.GetPlcInfo().Where(a => a.location == mst.CN_S_START_BIT).FirstOrDefault();
                        if (plcInfo != null)
                        {
                            if (plcInfo.deviceType == "2")
                            {
                                string taskName = mst.CN_S_BUSS_TYPE = getTaskType("3楼复称入缓存架", true);
                                string taskNameNG = mst.CN_S_BUSS_TYPE = getTaskType("3楼复称入缓存架NG", true);
                                CMMLog.Info($"起点任务类型:{taskName},{taskNameNG}");
                    
                                var FCTask = MongoDBSingleton.Instance.FindOne<TN_I_TASK_MST>(Query.And(Query.EQ("CN_S_START_BIT",mst.CN_S_START_BIT),Query.Or(Query.EQ("CN_S_BUSS_TYPE", taskName), Query.EQ("CN_S_BUSS_TYPE", taskNameNG))), "TN_I_TASK_MST");
                                if (FCTask != null)
                                {
                                    CMMLog.Info($"已查询到任务,任务号:{FCTask.CN_S_TASK_NO}");
                                    AMSHelper.SetStatus(FCTask.CN_S_TASK_NO, 1, "2", action.CN_S_DEVICE_CODE, true);
                                    WMSHelper.ExecuteState(FCTask.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE);
                                    iCallTask.DeleteTask(FCTask.CN_S_TASK_NO);
                                }
                            }
                        }
                    }
 
                    MongoDBSingleton.Instance.Remove<elevatorTask>(Query.And(Query.EQ("S_DT_LOC", mst.CN_S_START_BIT), Query.EQ("S_USE", "1")), RemoveFlags.None);
                    iCallTask.DeleteTask(mst.CN_S_TASK_NO);
                }
            }
            #endregion
 
            if (action.CN_N_ACTION_CODE == 13) {
                var task = iCallTask.FindTask(action.CN_S_TASK_NO);
                AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), "", "AGV调整任务优先级成功" + action.Ext1);
            }
 
            #region 任务状态委托(1-开始;3-开始取货;4-取货完成;5-开始卸货;6-卸货完成;2-完成)
            if (action.CN_N_ACTION_CODE == 1 || action.CN_N_ACTION_CODE == 2 || action.CN_N_ACTION_CODE == 4 || action.CN_N_ACTION_CODE == 6) {
                WorkFlowAction.TrackLog(action.CN_S_TASK_NO, 1, action.CN_N_ACTION_CODE, "");
                TN_I_TASK_MST mst = iCallTask.FindTask(action.CN_S_TASK_NO);
                if (mst != null) {
                    mst.CN_S_BUSS_TYPE = getTaskType(mst.CN_S_BUSS_TYPE, false);
 
                    if (string.IsNullOrEmpty(mst.CN_S_ForkliftNo) && !string.IsNullOrEmpty(action.CN_S_DEVICE_CODE))
                    {
                        MongoDBSingleton.Instance.Update<TN_I_TASK_MST>(Query.EQ("_id", mst._id), Update.Set("CN_S_ForkliftNo", action.CN_S_DEVICE_CODE), UpdateFlags.None);
                    }
                    if (action.CN_N_ACTION_CODE == 1)
                    {
                        AMSHelper.SetStatus(action.CN_S_TASK_NO, 1, "1", action.CN_S_DEVICE_CODE, true);
                        if (mst.CN_S_BUSS_TYPE != "3楼包装取料")
                            WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE);
                    }
                    if (action.CN_N_ACTION_CODE == 4)
                    {
                        CMMLog.Info($"收到信号:{action.CN_N_ACTION_CODE},任务号:{action.CN_S_TASK_NO},开始根据任务号查询主表中对应数据!");
                        AMSHelper.SetStatus(action.CN_S_TASK_NO, 1, "4", action.CN_S_DEVICE_CODE, true);
                        if (mst.CN_S_BUSS_TYPE == "包装线补空") PLCControl.PickUpBlankComplete(mst.CN_S_END_BIT, mst.CN_S_START_BIT);
                        //if (mst.CN_S_BUSS_TYPE == "3楼包装取料") PLCControl.CheckUpReqUnload(mst.CN_S_END_BIT, mst.CN_S_TASK_NO);
                        if (mst.CN_S_BUSS_TYPE == "缓存架入立库")
                        {
                            MongoDBSingleton.Instance.Update<ConnectingBits>(Query.EQ("Bit", mst.CN_S_START_BIT),Update.Set("trayCode", "").Set("state", "0"),UpdateFlags.None);
                        }
                        //if (mst.CN_S_BUSS_TYPE == "3楼缓存架入叠托") WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE);
                        if (mst.CN_S_BUSS_TYPE == "3楼打包下线")
                        {
                            //打包下线取货完成,将数据写入中间表
 
                        }
                        if (mst.CN_S_BUSS_TYPE.Contains("提升机"))
                        {
                            MongoDBSingleton.Instance.Update<elevatorTask>(Query.EQ("S_DT_LOC", mst.CN_S_START_BIT), Update.Set("S_USE","1"), UpdateFlags.None);
                        }
                    }
                    if (action.CN_N_ACTION_CODE == 6)
                    {
                        AMSHelper.SetStatus(action.CN_S_TASK_NO, 1, "6", action.CN_S_DEVICE_CODE, true);
                        if (mst.CN_S_BUSS_TYPE == "周转提升机")
                        {
                            //将数据记录到中间表
                            var agvloc = Settings.GetDDSiteList().Where(a => a.ddLoc == mst.CN_S_END_BIT).First();
                            if (agvloc != null)
                            {
                                var quantity = agvloc.quantity;
                                CMMLog.Info($"3楼包装补空,终点{mst.CN_S_END_BIT}站点个数:{quantity}");
                                var emptyInfo = MongoDBSingleton.Instance.FindOne<BZEmptyPoint>(Query.EQ("Bit", mst.CN_S_END_BIT), "BZEmptyPoint");
                                if (emptyInfo != null)
                                {
                                    MongoDBSingleton.Instance.Update<BZEmptyPoint>(Query.EQ("Bit", mst.CN_S_END_BIT), Update.Set("Quantity", quantity), UpdateFlags.None);
                                }
                                else
                                {
                                    MongoDBSingleton.Instance.Insert(new BZEmptyPoint { Bit = mst.CN_S_END_BIT, Quantity = quantity });
                                }
                            }
                        }
                        if (mst.CN_S_BUSS_TYPE == "3楼包装取料")
                        {
                            //卸货完成,中间表SecondWeighState  full改为1
                            UpdateBuilder update = Update.Set("full", 1);
                            MongoDBSingleton.Instance.Update<SecondWeighState>(Query.EQ("location", mst.CN_S_END_BIT), update, "SecondWeighState", UpdateFlags.None);
                        }
                        if (mst.CN_S_BUSS_TYPE == "3楼打包下线")
                        {
                            MongoDBSingleton.Instance.Update<ConnectingBits>(Query.EQ("Bit", mst.CN_S_END_BIT), Update.Set("state", "1"), UpdateFlags.None);
 
                        }
                        if (mst.CN_S_BUSS_TYPE == "缓存架入立库")
                        {
                            //货物入库后WMS要反馈入库信息给ERP,和ERP确认需要反馈的信息和节拍。每5托或者尾拖时间(1个小时)。按照标签重量入库
                            //var erpInfo = MongoDBSingleton.Instance.FindOne<ERPInfoTable>(Query.And(Query.EQ("batchNo",),Query.EQ("flage",1)), "ERPInfoTable");
                            //if(erpInfo != null)
                            //{
                            //    erpInfo.num = erpInfo.num + 1;
                            //    erpInfo.time = DateTime.Now;
                            //    MongoDBSingleton.Instance.Update<ERPInfoTable>(Query.And(Query.EQ("batchNo",),Query.EQ("flage", 1)), Update.Set("num", erpInfo.num).Set("time", erpInfo.time), UpdateFlags.None);
                            //    if (erpInfo.num == 5)
                            //    {
                            //        //反馈信息给erp
                            //
                            //
                            //
                            //        erpInfo.flage = 2;
                            //        MongoDBSingleton.Instance.Update<ERPInfoTable>(Query.EQ("batchNo", ), Update.Set("flage", erpInfo.flage), UpdateFlags.None);
                            //    }
                            //}
                            //else
                            //{
                            //    erpInfo = new ERPInfoTable
                            //    {
                            //        batchNo = ,
                            //        num = 1,
                            //        time = DateTime.Now,
                            //        flage = 1,
                            //    };
                            //    MongoDBSingleton.Instance.Insert(erpInfo);
                            //}
                        }
                    }
                    if (action.CN_N_ACTION_CODE == 2) {
                        AMSHelper.SetStatus(action.CN_S_TASK_NO, 1, "2", action.CN_S_DEVICE_CODE, true);
                        CMMLog.Info($"完成任务处理:收到2信号之后特殊任务类型处理:任务号:{mst.CN_S_TASK_NO},任务类型:{mst.CN_S_BUSS_TYPE}");
                        if(mst.CN_S_BUSS_TYPE == "包装线补空") ProcessHelper.EndPickUpDoorSafe(mst, action.CN_N_ACTION_CODE);
 
 
                        if (mst.CN_S_BUSS_TYPE != "3楼包装取料" && mst.CN_S_BUSS_TYPE != "包装间提升机") 
                            WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE);
 
                        //if (ERPService.SendERPTaskType.Contains(mst.CN_S_BUSS_TYPE) && ERPService.ERPSwitch01 == "1") ERPService.SendERPTaskInfo(mst);
 
                        //2024-08-08变更,计算当日入库出库数量
                        if (mst.CN_S_BUSS_TYPE == "缓存架入立库" || mst.CN_S_BUSS_TYPE == "成品出库")
                        {
                            string type = mst.CN_S_BUSS_TYPE == "缓存架入立库" ? "入库" : "出库";
 
                            DateTime time = DateTime.Now;
                            string year = time.ToString("yyyy");
                            string month = time.ToString("MM");
                            string day = time.ToString("dd");
                            
                            var qutInfo = MongoDBSingleton.Instance.FindOne<InAndOutQuantity>(Query.And(Query.EQ("Type", type), Query.EQ("Year",year), Query.EQ("Month",month), Query.EQ("Day",day)), "InAndOutQuantity");
                            if(qutInfo != null)
                            {
                                qutInfo.Quntity = qutInfo.Quntity + 1;
                                MongoDBSingleton.Instance.Update<InAndOutQuantity>(Query.And(Query.EQ("Type", type), Query.EQ("Year", year), Query.EQ("Month",month), Query.EQ("Day",day)), Update.Set("Quntity", qutInfo.Quntity), UpdateFlags.None);
                            }
                            else
                            {
                                qutInfo = new InAndOutQuantity
                                {
                                    Type = type,
                                    Year = year,
                                    Month = month,
                                    //Week = GetWeekOfMonth(DateTime.Now).ToString(),
                                    Day = day,
                                    Quntity = 1,
                                };
                                MongoDBSingleton.Instance.Insert(qutInfo);
                            }
 
                            //数量已经写入中间表 根据中间表数据,将数据写入通道
                            // 当日出库数量  40079
                            // 当日入库数量  40080
 
                            //获取今天的入库数量
 
                            int[] num = new int[2];
                            num[0] = MongoDBSingleton.Instance.FindOne<InAndOutQuantity>(Query.And(Query.EQ("Type", "出库"), Query.EQ("Year", year), Query.EQ("Month", month), Query.EQ("Day", day)), "InAndOutQuantity").Quntity;
                            num[1] = MongoDBSingleton.Instance.FindOne<InAndOutQuantity>(Query.And(Query.EQ("Type", "入库"), Query.EQ("Year", year), Query.EQ("Month", month), Query.EQ("Day", day)), "InAndOutQuantity").Quntity;
                            var wirteal = OITcpHelper.RegisterWriteOutPutMulti(new OITcpHelper.RegisterWriteOutPutModelMulti
                            {
                                addr = 78,
                                host = "10.15.73.26",
                                port = 5006,
                                data = num
                            });
                        }
                        if (mst.CN_S_BUSS_TYPE == "3楼包装取料")
                        {
                            CMMLog.Info("进入三楼包装取料流程");
                            //判断是否是复秤入缓存架任务
                            var plcInfo = Settings.GetPlcInfo().Where(a => a.location == mst.CN_S_START_BIT).FirstOrDefault();
                            if(plcInfo != null)
                            {
                                CMMLog.Info($"查询起点信息:{plcInfo.deviceType}");
                                if(plcInfo.deviceType == "2")
                                {
                                    string taskName = mst.CN_S_BUSS_TYPE = getTaskType("3楼复称入缓存架", true);
                                    string taskNameNG = mst.CN_S_BUSS_TYPE = getTaskType("3楼复称入缓存架NG", true);
                                    CMMLog.Info($"起点任务类型:{taskName},{taskNameNG}");
                                    var FCTask = MongoDBSingleton.Instance.FindOne<TN_I_TASK_MST>(Query.And(Query.EQ("CN_S_START_BIT", mst.CN_S_START_BIT), Query.Or(Query.EQ("CN_S_BUSS_TYPE", taskName), Query.EQ("CN_S_BUSS_TYPE", taskNameNG))), "TN_I_TASK_MST");
                                    if(FCTask != null)
                                    {
                                        CMMLog.Info($"已查询到任务,任务号:{FCTask.CN_S_TASK_NO}");
                                        AMSHelper.SetStatus(FCTask.CN_S_TASK_NO, 1, "2", action.CN_S_DEVICE_CODE, true);
                                        WMSHelper.ExecuteState(FCTask.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE);
                                        iCallTask.DeleteTask(FCTask.CN_S_TASK_NO);
                                    }
                                    else
                                    {
                                        CMMLog.Info("未查询到任务");
                                    }
                                }
                            }
                        }
                        if (mst.CN_S_END_BIT.Contains("TSJ"))
                        {
                            ProcessHelper.createDTTask();
                        }
 
                        MongoDBSingleton.Instance.Remove<elevatorTask>(Query.And(Query.EQ("S_DT_LOC", mst.CN_S_START_BIT),Query.EQ("S_USE", "1")), RemoveFlags.None);
                        //if (ERPService.SendERPTaskType.Contains(mst.CN_S_BUSS_TYPE) && ERPService.ERPSwitch01 == "1") ERPService.SendERPTaskInfo(mst);
                        iCallTask.DeleteTask(mst.CN_S_TASK_NO);
                    }
                }
            }
            #endregion
 
            #region 小车状态写入通道 (1-开始;2-完成 4-取货完成 6-卸货完成)
            //if (action.CN_N_ACTION_CODE == 1 || action.CN_N_ACTION_CODE == 2 || action.CN_N_ACTION_CODE == 4 || action.CN_N_ACTION_CODE == 6)
            //{
            //    TN_I_TASK_MST mst = iCallTask.FindTask(action.CN_S_TASK_NO);
            //    CMMLog.Info($"小车状态写入通道处理开始");
            //    if (mst != null)
            //    {
            //        mst.CN_S_BUSS_TYPE = getTaskType(mst.CN_S_BUSS_TYPE, false);
            //        CMMLog.Info($"车号:{mst.CN_S_ForkliftNo}");
            //        var stateInfo = Settings.GetAGVStateList().Where(a => a.AgvNo == mst.CN_S_ForkliftNo).FirstOrDefault();
            //        if (stateInfo != null)
            //        {
            //            if(action.CN_N_ACTION_CODE == 1)
            //            {
            //                //开始,往通道写入1
            //                var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
            //                {
            //                    host = stateInfo.ip,
            //                    port = stateInfo.port,
            //                    addr = stateInfo.writeAddr + 5,
            //                    data = 1
            //                });
            //                CMMLog.Info($"在通道{stateInfo.writeAddr + 5}中写入1,ip:{stateInfo.ip},端口:{stateInfo.port}");
            //            }
            //            if (action.CN_N_ACTION_CODE == 2)
            //            {
            //                //完成,往通道写入0
            //                var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
            //                {
            //                    host = stateInfo.ip,
            //                    port = stateInfo.port,
            //                    addr = stateInfo.writeAddr + 5,
            //                    data = 0
            //                });
            //                CMMLog.Info($"在通道{stateInfo.writeAddr + 5}中写入0,ip:{stateInfo.ip},端口:{stateInfo.port}");
            //            }
            //            if(action.CN_N_ACTION_CODE == 4)
            //            {
            //                //取货完成,往通道写入1
            //                var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
            //                {
            //                    host = stateInfo.ip,
            //                    port = stateInfo.port,
            //                    addr = stateInfo.writeAddr + 6,
            //                    data = 1
            //                });
            //                CMMLog.Info($"在通道{stateInfo.writeAddr + 5}中写入1,ip:{stateInfo.ip},端口:{stateInfo.port}");
            //            }
            //            if(action.CN_N_ACTION_CODE == 6)
            //            {
            //                //卸货完成,往通道写入0
            //                var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
            //                {
            //                    host = stateInfo.ip,
            //                    port = stateInfo.port,
            //                    addr = stateInfo.writeAddr + 6,
            //                    data = 0
            //                });
            //                CMMLog.Info($"在通道{stateInfo.writeAddr + 5}中写入1,ip:{stateInfo.ip},端口:{stateInfo.port}");
            //            }
            //        }
            //        else CMMLog.Info($"小车{mst.CN_S_ForkliftNo}信号未配置");
            //    }
            //}
            #endregion
 
            #region 电动门A门交管信号(1023-开门 1025-关门)  B门交管信号(1013-开门 6--关门)
            if (action.CN_N_ACTION_CODE == 1023)
            {
                CMMLog.Info($"收到信号{action.CN_N_ACTION_CODE},门号:{action.Ext2}");
                //电动门开门
                var doorInfo = Settings.GetPlcInfo().Where(a => a.Extend == action.Ext2 && a.enable == 1).FirstOrDefault();
                if(doorInfo != null)
                {
                    //电动门开门步骤:
                    //1、在通道【40101】中写入1,发送开门信号
                    //2、读取通道【40001】中的值,如果为1,表示开门到位,通知小车进去
                    var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
                    {
                        host = doorInfo.ip,
                        port = doorInfo.port,
                        addr = doorInfo.writeAddr,
                        data = 1
                    });
                    CMMLog.Info($"发送开门信号,在通道{doorInfo.writeAddr}中写入1,ip:{doorInfo.ip},端口:{doorInfo.port}");
 
                    var result = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
                    {
                        dataNum = 1,
                        addr = doorInfo.readAddr,
                        host = doorInfo.ip,
                        port = doorInfo.port
                    });
                    CMMLog.Info($"电动门开门流程:读取电动门通道号为:{doorInfo.readAddr}里面的值为{JsonConvert.SerializeObject(result.result)}");
                    if (result != null && result.errCode == 0)
                    {
                        //Console.WriteLine($"电动门开门流程:读取电动门通道号为:{doorInfo.readAddr}里面的值为{result.result[0]},{doorInfo.readAddr + 1}里面的值为{result.result[1]}");
                        if (result.result[0] == 2 )
                        {
                            //推送小车进去
                            CMMLog.Info($"电动门已经打开,门号:{action.Ext2}");
                            
                            TSHelper.Traffic(action.Ext2);
 
                            writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
                            {
                                host = doorInfo.ip,
                                port = doorInfo.port,
                                addr = doorInfo.writeAddr,
                                data = 2
                            });
                            CMMLog.Info($"电动门关门流程,在通道{doorInfo.writeAddr}中写入2,ip:{doorInfo.ip},端口:{doorInfo.port}");
                        }
                    }
                    else CMMLog.Info($"电动门开门流程:未读取到包装机通道{doorInfo.readAddr}里面的数据!!!result:{JsonConvert.SerializeObject(result)}");
                }
                else CMMLog.Info($"门号为【{action.Ext2}】的门为在配置文件配置或者未启用");
            }
            else if(action.CN_N_ACTION_CODE == 1025)
            {
                //电动门关门
                var doorInfo = Settings.GetPlcInfo().Where(a => a.Extend == action.Ext2 && a.enable == 1).FirstOrDefault();
                if (doorInfo != null)
                {
                    //电动门关门步骤
                    //1、小车通过电动门后,在通道【40101】中写入2
                    var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
                    {
                        host = doorInfo.ip,
                        port = doorInfo.port,
                        addr = doorInfo.writeAddr,
                        data = 3
                    });
                    CMMLog.Info($"电动门关门流程,在通道{doorInfo.writeAddr}中写入3,ip:{doorInfo.ip},端口:{doorInfo.port}");
                }
                else CMMLog.Info($"门号为【{action.Ext2}】的门为在配置文件配置或者未启用");
            }
            #endregion
 
            #region   3楼设备任务
 
            //起点安全对接      1012:安全请求进入     4:安全请求退出
            if (action.CN_N_ACTION_CODE == 1012 || action.CN_N_ACTION_CODE == 4 || action.CN_N_ACTION_CODE == 1312)
            {
                CMMLog.Info($"起点安全对接:收到信号:{action.CN_N_ACTION_CODE},任务号:{action.CN_S_TASK_NO},开始根据任务号查询主表中对应数据!");
                var mst = iCallTask.FindTask(action.CN_S_TASK_NO);
                if (mst != null)
                {
                    mst.CN_S_BUSS_TYPE = getTaskType(mst.CN_S_BUSS_TYPE, false);
                    CMMLog.Info($"起点安全对接:收到任务号:{mst.CN_S_TASK_NO},任务类型:{mst.CN_S_BUSS_TYPE},任务信号:{action.CN_N_ACTION_CODE}");
                    //3楼拆盘补空:拆盘机补空托盘            3楼包装补空:包装机补空托
                    if (mst.CN_S_BUSS_TYPE == "3楼包装取料" || mst.CN_S_BUSS_TYPE == "3楼缓存架入叠托" || mst.CN_S_BUSS_TYPE == "3楼叠盘下线" || mst.CN_S_BUSS_TYPE == "3楼打包下线" || mst.CN_S_BUSS_TYPE.Contains("提升机"))
                    {   
                        CMMLog.Info($"起点安全对接:即将进入任务流程:{mst.CN_S_BUSS_TYPE},状态号为:{action.CN_N_ACTION_CODE}");
                        ProcessHelper.StartPickUpDoorSafe(mst, action.CN_N_ACTION_CODE);
                    }
                }
                else
                {
                    CMMLog.Info("未查询到任务");
                }
            }
 
            //滚筒车起点到位信号、取货完成信号    1112        1212     3、4          只对滚筒车对接
            if (action.CN_N_ACTION_CODE == 1112 || action.CN_N_ACTION_CODE == 1212)
            {
                var mst = iCallTask.FindTask(action.CN_S_TASK_NO);
                if (mst != null)
                {
                    mst.CN_S_BUSS_TYPE = getTaskType(mst.CN_S_BUSS_TYPE, false);
                    if (mst.CN_S_BUSS_TYPE == "3楼包装取料")
                    {
                        ProcessHelper.PickupAndUnload(mst, action.CN_N_ACTION_CODE);
                    }
                }
            }
 
            //终点安全对接      1013:安全请求进入     6:安全请求退出
            if (action.CN_N_ACTION_CODE == 1013 || action.CN_N_ACTION_CODE == 6 || action.CN_N_ACTION_CODE == 1312)
            {
                CMMLog.Info($"终点安全对接:收到信号:{action.CN_N_ACTION_CODE},任务号:{action.CN_S_TASK_NO},开始根据任务号查询主表中对应数据!");
                TN_I_TASK_MST mst = iCallTask.FindTask(action.CN_S_TASK_NO);
                if (mst != null)
                {
                    mst.CN_S_BUSS_TYPE = getTaskType(mst.CN_S_BUSS_TYPE, false);
                    CMMLog.Info($"终点安全对接:收到任务号:{mst.CN_S_TASK_NO},任务类型:{mst.CN_S_BUSS_TYPE},任务信号:{action.CN_N_ACTION_CODE}");
                    //3楼拆盘补空:拆盘机补空托盘            3楼包装补空:包装机补空托
                    if (mst.CN_S_BUSS_TYPE == "3楼包装补空" || mst.CN_S_BUSS_TYPE == "3楼包装取料" || mst.CN_S_BUSS_TYPE == "3楼复称入缓存架" || mst.CN_S_BUSS_TYPE == "3楼缓存架入叠托" || mst.CN_S_BUSS_TYPE == "3楼拆盘补空" || mst.CN_S_BUSS_TYPE == "包装线补空" || mst.CN_S_BUSS_TYPE == "3楼打包下线" || mst.CN_S_BUSS_TYPE == "3楼成品出库" || mst.CN_S_BUSS_TYPE.Contains("提升机") || mst.CN_S_BUSS_TYPE == "转运到包装机" || mst.CN_S_BUSS_TYPE == "1楼辅材入2楼")
                    {
                        ProcessHelper.EndPickUpDoorSafe(mst, action.CN_N_ACTION_CODE);
                    }
                }
            }
 
            //滚筒车终点到位信号、卸货完成信号     1113        1213        5、6      只对滚筒车对接
            if (action.CN_N_ACTION_CODE == 4 || action.CN_N_ACTION_CODE == 1213)
            {
                var mst = iCallTask.FindTask(action.CN_S_TASK_NO);
                CMMLog.Info($"4 或 1213 信号,{mst.CN_S_BUSS_TYPE},{mst.CN_S_END_BIT}");
                if (mst != null)
                {
                    mst.CN_S_BUSS_TYPE = getTaskType(mst.CN_S_BUSS_TYPE, false);
 
                    //3楼拆盘补空:拆盘机补空托盘            3楼包装补空:包装机补空托
                    if (mst.CN_S_BUSS_TYPE == "3楼包装取料") ProcessHelper.DiscRemoverEmptySupport(mst, action.CN_N_ACTION_CODE);
                }
            }
 
            //缓存架入叠托,小车扫码
            if(action.CN_N_ACTION_CODE == 1313)
            {
                TN_I_TASK_MST mst = iCallTask.FindTask(action.CN_S_TASK_NO);
                if(mst != null)
                {
                    mst.CN_S_BUSS_TYPE = getTaskType(mst.CN_S_BUSS_TYPE, false);
                    CMMLog.Info($"收到信号:{action.CN_N_ACTION_CODE},任务号:{action.CN_S_TASK_NO},任务类型:{mst.CN_S_BUSS_TYPE}");
                    if (mst.CN_S_BUSS_TYPE.Contains("3楼包装取料"))
                    {
                        //将读取复称重量的流程放到1313流程下,获取到wms传的终点,进行改道
                        var plc = Settings.GetPlcInfo().Where(a => a.location == mst.CN_S_END_BIT).FirstOrDefault();
                        if (plc != null)
                        {
                            PLCControl.EcheckWeighingPlatform1313(plc.deviceType, mst);
                            //AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "小车扫码");
                        }
                        else CMMLog.Info($"点位为{mst.CN_S_END_BIT}的设备未配置");
                    }
                    if (mst.CN_S_BUSS_TYPE == "叠包提升机")
                    {
                        var plc = Settings.GetPlcInfo().Where(a => a.location == mst.CN_S_END_BIT).FirstOrDefault();
                        if (plc != null)
                        {
                            PLCControl.CacheStackingMouth1313(plc.deviceType, mst);
                            //AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "小车扫码");
                        }
                        else CMMLog.Info($"点位为{mst.CN_S_END_BIT}的设备未配置");
                    }
                    
                }
            }
 
            //立库出库
            //if (action.CN_N_ACTION_CODE == 1105)
            //{
            //    TN_I_TASK_MST mst = iCallTask.FindTask(action.CN_S_TASK_NO);
            //    if (mst != null)
            //    {
            //        CMMLog.Info($"1105信号,{mst.CN_S_BUSS_TYPE},{mst.CN_S_END_BIT}");
            //        OutWareTask(mst);
            //    }
            //}
 
            #endregion
 
            return iResult;
        }
 
        
 
        #region AGV车体状态信息
        public void HangChaAGVEvent(HangChaAGV _hangChaAGV) {
        }
        public void HangChaAGVEvent(List<HangChaAGV> agvs) {
 
        }
 
        #endregion
 
        /// <summary>
        /// 周转托盘位
        /// </summary>
        public class BZEmptyPoint
        {
            public ObjectId _id { get; set; }
            /// <summary>
            /// 空托缓存点
            /// </summary>
            public string Bit { get; set; }
            /// <summary>
            /// 托盘数量
            /// </summary>
            public int Quantity { get; set; }
        }
 
        /// <summary>
        /// 立库入库ERP节拍
        /// </summary>
        public class ERPInfoTable
        {
            public ObjectId _id { get; set; }
            /// <summary>
            /// 批次号
            /// </summary>
            public string batchNo { get; set; }
            /// <summary>
            /// 入库数量
            /// </summary>
            public int num { get; set; } = 1;
            /// <summary>
            /// 尾托时间
            /// </summary>
            public DateTime time { get; set; }
            /// <summary>
            /// 是否执行完成  1:待执行 2:执行完成
            /// </summary>
            public int flage { get; set; } = 1;
        }
 
        #region 设备合格率清单
        public class ProductList
        {
            public ObjectId _id { get; set; }
            /// <summary>
            /// 日期
            /// </summary>
            public string Date { get; set; }
            /// <summary>
            /// 设备
            /// </summary>
            public string machine { get; set; }
            /// <summary>
            /// 设备生产数
            /// </summary>
            public double total { get; set; }
            /// <summary>
            /// 合格数
            /// </summary>
            public double qualifiedQuantity { get; set; }
            /// <summary>
            /// 合格率
            /// </summary>
            public double percentOfPass { get; set; }
            /// <summary>
            /// 当天总合格数
            /// </summary>
            public double overallPassRate { get; set; }
        }
        #endregion
 
        #region 打包下线口接驳位
        public class ConnectingBits
        {
            public ObjectId _id { get; set; }
            /// <summary>
            /// 货位编码
            /// </summary>
            public string Bit { get; set; }
            /// <summary>
            /// 托盘号
            /// </summary>
            public string trayCode { get; set; }
            /// <summary>
            /// 货位状态 0 无货  1 有货
            /// </summary>
            public string state { get; set; }
            /// <summary>
            /// 时间戳
            /// </summary>
            public string timeCuo { get; set; }
        }
        public class InAndOutQuantity
        {
            /// <summary>
            /// 类型 出库 - 入库
            /// </summary>
            public string Type { get; set; }
            /// <summary>
            /// 年
            /// </summary>
            public string Year { get; set; }
            /// <summary>
            /// 月
            /// </summary>
            public string Month { get; set; }
            /// <summary>
            /// 周
            /// </summary>
            //public string Week { get; set; }
            /// <summary>
            /// 日
            /// </summary>
            public string Day { get; set; }
            /// <summary>
            /// 数量
            /// </summary>
            public int Quntity { get; set; }
        }
 
        #endregion
 
 
    }
}