1
Jianw
2025-07-09 f6f5e6b632d6649386a380558d84003f3de7ec6c
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
--[[
   编码: WMS-38-XX
   名称:WCS任务启动
   作者:李帅帅
   日期:2025-06-18
 
   函数: WcsTaskRun
   功能:  推送任务给设备
 
   更改记录:
 
--]]
json  = require("json")
mobox = require("OILua_JavelinExt")
m3    = require("oi_base_mobox")
 
-- 写数据到PLC
local function WriteS7PLCCommsData(strLuaDEID, devicecode, commcode, comm_value)
    local nRet, strRetInfo, canshu
 
    -- comm_value为数组 {1}、{1,2} 可以写DInt
    local canshu = {
        device_code = devicecode,
        comm_code = commcode,
        value = comm_value
    }
 
    local strKey = "OpenInfo"
    local strSecret = "OpenInfoSecret"
    local strHeader = ''
    -- 获取Header
    nRet, strHeader = mobox.genReqVerify(strKey, strSecret)
    strHeader = string.gsub(strHeader, "ReqTime", "\nReqTime")
    strHeader = string.gsub(strHeader, "ReqVerify", "\nReqVerify")
    lua.DebugEx(strLuaDEID, "strHeader:", strHeader)
    local strurl = "http://192.168.1.205:5121/api/devctrl/writedata"
    local strBody = lua.table2str(canshu)
    lua.DebugEx(strLuaDEID, "接口调用前参数:", strBody)
    nRet, strRetInfo = mobox.sendHttpRequest(strurl, strHeader, strBody)
    if (nRet ~= 0 or strRetInfo == '') then
        lua.stop(strLuaDEID,
            "S7PLC 写入失败!  device_code = " .. devicecode .. " comm_code = " .. commcode .. "错误码:" .. nRet .. strRetInfo)
        return nRet
    end
    lua.Debug(strLuaDEID, debug.getinfo(1), "写PLC返回信息:", strRetInfo)
    local api_ret = json.decode(strRetInfo)
    if (api_ret.err_code ~= 0) then
        lua.stop(strLuaDEID,
            "S7PLC 写入失败! device_code = " ..
            devicecode .. " comm_code = " .. commcode .. "错误码:" .. api_ret.err_code .. " --> " .. api_ret.err_msg)
        return api_ret.err_code
    end
    return api_ret.err_code
end
-- 读PLC信号
local function ReadS7PLCCommsData(strLuaDEID, devicecode, commcode)
    local nRet, strRetInfo, api_ret
    -- 开始调用
    local canshu = {
        device_code = devicecode,
        comm_code = commcode
    }
 
    local strKey = "OpenInfo"
    local strSecret = "OpenInfoSecret"
    local strHeader = ''
    -- 获取Header
    nRet, strHeader = mobox.genReqVerify(strKey, strSecret)
    strHeader = string.gsub(strHeader, "ReqTime", "\nReqTime")
    strHeader = string.gsub(strHeader, "ReqVerify", "\nReqVerify")
    lua.DebugEx(strLuaDEID, "strHeader:", strHeader)
 
    local strBody = lua.table2str(canshu)
    local strurl = "http://192.168.1.205:5121/api/devctrl/GetCommData"
    lua.DebugEx(strLuaDEID, "接口调用前参数:", strBody)
 
    nRet, strRetInfo = mobox.sendHttpRequest(strurl, strHeader, strBody)
    lua.DebugEx(strLuaDEID, "接口调用后返回信息:", strRetInfo)
    if (nRet ~= 0 or strRetInfo == '') then
        lua.Error(strLuaDEID, debug.getinfo(1),
            "调用OIDeviceCommS接口ReadData失败! device_code = " .. devicecode .. " comm_code = " .. commcode ..
            "错误码:" .. nRet .. "  " .. strRetInfo)
    end
    local api_ret = json.decode(strRetInfo)
    if (api_ret.err_code ~= 0) then
        lua.Stop(strLuaDEID,
            "调用OIDeviceCommS接口ReadData失败!  device_code = " .. devicecode .. " comm_code = " .. commcode ..
            "错误码:" .. api_ret.err_code .. "  " .. api_ret.err_msg)
        return
    end
 
    local retinfo = api_ret.result[1].value
    return retinfo
end
 
-- 写连续数据到S7的通讯项
local function WriteMultiS7PLCCommsData(strLuaDEID, devicecode, commcode, comm_value)
    local nRet, strRetInfo, canshu
 
    --  comm_value为数组 {1}、{1,2} 可以写DInt
    local canshu = {
        device_code = devicecode,
        comm_code = commcode,
        value = comm_value
    }
 
    local strKey = "OpenInfo"
    local strSecret = "OpenInfoSecret"
    local strHeader = ''
    -- 获取Header
    nRet, strHeader = mobox.genReqVerify(strKey, strSecret)
    strHeader = string.gsub(strHeader, "ReqTime", "\nReqTime")
    strHeader = string.gsub(strHeader, "ReqVerify", "\nReqVerify")
    lua.DebugEx(strLuaDEID, "strHeader:", strHeader)
    local strurl = "http://192.168.1.205:5121/api/devctrl/WriteMultiData"
    local strBody = lua.table2str(canshu)
    lua.DebugEx(strLuaDEID, "接口调用前参数:", strBody)
    nRet, strRetInfo = mobox.sendHttpRequest(strurl, strHeader, strBody)
    if (nRet ~= 0 or strRetInfo == '') then
        lua.Stop(strLuaDEID,
            "S7PLC 写入失败!  device_code = " .. devicecode .. " comm_code = " .. commcode .. "错误码:" .. nRet ..
            "  " .. strRetInfo)
        return
    end
    lua.DebugEx(strLuaDEID, "写PLC返回信息:", strRetInfo)
    local api_ret = json.decode(strRetInfo)
    if (api_ret.err_code ~= 0) then
        lua.Stop(strLuaDEID,
            "S7PLC 写入失败! device_code = " .. devicecode .. " comm_code = " .. commcode .. "错误码:" ..
            api_ret.err_code .. " --> " .. api_ret.err_msg)
    end
 
    return nRet
end
 
-- 将我们的任务号 转换为写入线体的任务号
local function WritePlcTaskNo(strLuaDEID, taskno)
    -- 2. 截取倒数第五位到倒数第八位(共4个字符)
    local no1 = string.sub(taskno, -9, -6)
    -- 1. 截取最后四位
    local no2 = string.sub(taskno, -4)
 
    -- 转换为数字再转回字符串(自动去除前导零)
    local Numberno1 = tonumber(no1)
    -- 转换为数字再转回字符串(自动去除前导零)
    local Numberno2 = tonumber(no2)
 
    return Numberno1, Numberno2
end
--推送堆垛机任务
--taskType 任务类型0=无 1=入库 2=出库 3=移库
--deviceType 1=前叉 2=后叉 3=双叉
 
local function SendTask(strLuaDEID, beforeTask, afterTask, taskType, deviceType)
    --获取前叉数据
    local beforetask1 = 0
    local beforetask2 = 0
    local startRow1 = 0
    local startCol1 = 0
    local startLayer1 = 0
    local endRow1 = 0
    local endCol1 = 0
    local endLayer1 = 0
    local deviceCode = "TC1" --堆垛机编码
    --获取前叉任务数据
    if (beforeTask ~= nil and beforeTask ~= "") then
        beforetask1, beforetask2 = WritePlcTaskNo(strLuaDEID, beforeTask.code)
        --获取起点信息
        local nRet, StartLoc1
        local StartLocSelect1 = "S_CODE = '" .. beforeTask.start_loc_code .. "'"
        nRet, StartLoc1 = m3.GetDataObjByCondition(strLuaDEID, "Location", StartLocSelect1)
        if (nRet ~= 0) then
            lua.Stop(strLuaDEID,
                "获取起点货位信息有误! " .. StartLoc1 .. " SQL条件: " .. StartLocSelect1)
            return
        end
        startRow1 = StartLoc1.row
        startCol1 = StartLoc1.col
        startLayer1 = StartLoc1.layer
        if (StartLoc1.roadway == 2) then
            deviceCode = "TC2"
        end
        lua.DebugEx(strLuaDEID, '堆垛机任务推送:查询起点货位', StartLoc1)
 
        --获取终点信息
        local Endtoc1
        local EndLocSelect1 = "S_CODE = '" .. beforeTask.end_loc_code .. "'"
        nRet, Endtoc1 = m3.GetDataObjByCondition(strLuaDEID, "Location", EndLocSelect1)
        if (nRet ~= 0) then
            lua.Stop(strLuaDEID,
                "获取起点货位信息有误! " .. Endtoc1 .. " SQL条件: " .. EndLocSelect1)
            return
        end
        endRow1 = Endtoc1.row
        endCol1 = Endtoc1.col
        endLayer1 = Endtoc1.layer
        lua.DebugEx(strLuaDEID, '堆垛机任务推送:查询起点货位', Endtoc1)
    end
    local startRow2 = 0
    local startCol2 = 0
    local startLayer2 = 0
    local endRow2 = 0
    local endCol2 = 0
    local endLayer2 = 0
    local Aftertask1 = 0
    local Aftertask2 = 0
 
    --判断对应巷道堆垛机有无任务
    local TaskNo = ReadS7PLCCommsData(strLuaDEID, deviceCode, { "27" })
    if (TaskNo[1] ~= 0 or TaskNo[2] ~= 0) then
        lua.DebugEx(strLuaDEID, '堆垛机任务推送:推送失败', "查询前叉存在任务")
        return 1
    end
 
    --获取后叉任务数据
    if (afterTask ~= nil and afterTask ~= "") then
        Aftertask1, Aftertask2 = WritePlcTaskNo(strLuaDEID, afterTask.code)
        --获取起点信息
        local nRet, StartLoc2
        local StartLocSelect2 = "S_CODE = '" .. afterTask.start_loc_code .. "'"
        nRet, StartLoc2 = m3.GetDataObjByCondition(strLuaDEID, "Location", StartLocSelect2)
        if (nRet ~= 0) then
            lua.Stop(strLuaDEID,
                "获取起点货位信息有误! " .. StartLoc2 .. " SQL条件: " .. StartLocSelect2)
            return
        end
        if (StartLoc2.roadway == 2) then
            deviceCode = "TC1"
        end
        startRow2 = StartLoc2.row
        startRow2 = StartLoc2.col
        startRow2 = StartLoc2.layer
        lua.DebugEx(strLuaDEID, '堆垛机任务推送:查询起点货位', StartLoc2)
 
        --获取终点信息
        local Endtoc2
        local EndLocSelect2 = "S_CODE = '" .. beforeTask.end_loc_code .. "'"
        nRet, Endtoc2 = m3.GetDataObjByCondition(strLuaDEID, "Location", EndLocSelect2)
        if (nRet ~= 0) then
            lua.Stop(strLuaDEID,
                "获取起点货位信息有误! " .. Endtoc2 .. " SQL条件: " .. EndLocSelect2)
            return
        end
        endRow2 = Endtoc2.row
        endCol2 = Endtoc2.col
        endLayer2 = Endtoc2.layer
    end
    --拼接批量写入数据
    local value = { deviceType, startRow1, startCol1, startLayer1, endRow1, endCol1, endLayer1, taskType, startRow2,
        startCol2, startLayer2, endRow2, endCol2, endLayer2, taskType, 1, 0, 0, 0, 0, 0, 0, 0, 0, beforetask1,
        beforetask2, Aftertask1, Aftertask2 }
    local code = WriteMultiS7PLCCommsData(strLuaDEID, deviceCode, "03_WRITE", value)
    --下发成功修改任务状态
    if code == 0 then
        if (beforeTask ~= nil and beforeTask ~= "") then
            local nRet, updateTask
            local strCondition = "S_CODE = '" .. beforeTask.code .. "' "
            nRet, updateTask = mobox.updateDataAttrByCondition(strLuaDEID, "Task", strCondition,
                "S_B_STATE = '已推送',N_B_STATE = 1")
            if (nRet ~= 0) then
                lua.Stop(strLuaDEID, " 堆垛机推送=》 修改任务" .. beforeTask.code .. "状态失败! " .. updateTask)
                return
            end
        end
        if (afterTask ~= nil and afterTask ~= "") then
            local nRet, updateTask
            local strCondition = "S_CODE = '" .. afterTask.code .. "' "
            nRet, updateTask = mobox.updateDataAttrByCondition(strLuaDEID, "Task", strCondition,
                "S_B_STATE = '已推送',N_B_STATE = 1")
            if (nRet ~= 0) then
                lua.Stop(strLuaDEID, " 堆垛机推送=》 修改任务" .. afterTask.code .. "状态失败! " .. updateTask)
                return
            end
        end
    end
end
 
--推送输送线空托搬运任务
local function SendEmpty(strLuaDEID, Wcstask)
    --判断任务起点有无托盘
    local work = ReadS7PLCCommsData(strLuaDEID, "S7_LINE_01", { "27" })
    if work[1] == 3 then
        --推送任务
 
        local high_uint, low_uint, nRet
        high_uint, low_uint = WritePlcTaskNo(strLuaDEID, Wcstask.code)
        --写入目标地址
        nRet = WriteS7PLCCommsData(strLuaDEID, "S7_LINE_01", Wcstask.start_loc_code .. "-TARGRT_ADDRESS",
            { Wcstask.end_loc_code });
        if nRet ~= 0 then
            lua.Stop(strLuaDEID, "呼叫空托=》输送线任务下发失败")
            return 1
        end
        nRet = WriteS7PLCCommsData(strLuaDEID, "S7_LINE_01", Wcstask.start_loc_code .. "-S_TASK_NO",
            { high_uint, low_uint });
        if nRet ~= 0 then
            lua.Stop(strLuaDEID, "呼叫空托=》输送线任务下发失败")
            return 1
        end
 
        --修改任务状态
        local nRet, UpdateTask
        nRet, UpdateTask = mobox.updateDataAttrByCondition(strLuaDEID, "Task",
            "S_CODE = '" .. Wcstask.code .. "'", "N_B_STATE = 1,S_B_STATE = '已推送'")
        if nRet ~= 0 then
            lua.Stop(strLuaDEID, "更新输送线呼叫空托状态" .. UpdateTask .. "失败! ")
            return 1
        end
    end
end
 
--推送出库任务(输送线任务)
local function SendPutOutSssx(strLuaDEID, Wcstask)
    -- local dint_value = Wcstask.code & 0xFFFFFFFF
 
    -- 提取高16位和低16位(无符号)
    -- local high_uint = (dint_value >> 16) & 0xFFFF
    --local low_uint = dint_value & 0xFFFF
    --local LocSelect = "S_CODE = '"attrs.code"'"
    local high_uint, low_uint
    high_uint, low_uint = WritePlcTaskNo(strLuaDEID, Wcstask.code)
    --写入目标地址
    WriteS7PLCCommsData(strLuaDEID, "S7_LINE_01", Wcstask.start_loc_code .. "-TARGRT_ADDRESS", { 1063 });
    WriteS7PLCCommsData(strLuaDEID, "S7_LINE_01", Wcstask.start_loc_code .. "-S_TASK_NO", { high_uint, low_uint });
    -- WriteS7PLCCommsData(strLuaDEID, "S7_LINE", Wcstask.end_loc_code + "-TARGRT_ADDRESS");
 
 
 
    local nRet, UpdateTask
    nRet, UpdateTask = mobox.updateDataAttrByCondition(strLuaDEID, "Task",
        "S_CODE = '" .. Wcstask.code .. "'", "N_B_STATE = 1,S_B_STATE = '已推送'")
    if nRet ~= 0 then
        lua.Stop(strLuaDEID, "更新输送线出库任务状态" .. UpdateTask .. "失败! ")
        return 1
    end
end
--[[
  Wcstask:需要移库的出库任务
  StartLoc:起点货位信息
  Endloc:分配的终点
grouby:分组,为后叉任务号
--]]
local function CreatMoveTask(strLuaDEID, Wcstask, StartLoc, Endloc, grouby)
    -- region 创建移库任务
    local strCode, nRet
    local strHeader = 'TA' .. os.date("%y%m%d") .. '-'
    nRet, strCode = mobox.getSerialNumber("任务", strHeader, 5)
    if (nRet ~= 0) then lua.Error(strLuaDEID, debug.getinfo(1), '申请【任务】编码失败!' .. strCode) end
    local Task = m3.AllocObject(strLuaDEID, "Task")
    Task.code = strCode
    Task.op_code = Wcstask.op_code       -- 作业编码
    Task.op_name = Wcstask.op_name       -- 作业名称
    Task.factory = Wcstask.factory       -- 工厂
    Task.cntr_code = Wcstask.cntr_code   -- 托盘
    Task.start_lan = Wcstask.start_aisle -- 巷道
 
 
    -- 起点
    Task.start_wh_code = StartLoc.start_wh_code
    Task.start_area_code = StartLoc.start_area_code
    Task.start_loc_code = StartLoc.code
    Task.groupby = grouby
 
    -- 终点
    Task.end_wh_code = StartLoc.start_wh_code
    Task.end_area_code = StartLoc.start_area_code
    Task.end_loc_code = Endloc
 
    -- 创建后叉任务
    nRet, Aftertask = m3.CreateDataObj(strLuaDEID, Aftertask)
    if (nRet ~= 0) then
        lua.Stop(strLuaDEID, "创建前叉堆垛机任务失败!" .. Aftertask)
        return
    end
end
--推送堆垛机任务(出库任务)
local function SendPutOut(strLuaDEID, Wcstask)
    --获取作业起点货位信息
    local nRet, StartLoc
    local StartLocSelect = "S_CODE = '" .. Wcstask.start_loc_code .. "'"
    nRet, StartLoc = m3.GetDataObjByCondition(strLuaDEID, "Location", StartLocSelect)
    if (nRet ~= 0) then
        lua.Stop(strLuaDEID,
            "获取任务起点货位信息有误! " .. StartLoc .. " SQL条件: " .. StartLocSelect)
        return
        -- return 2,"获取起点货位信息有误! " .. StartLoc .. " SQL条件: " .. StartLocSelect;
    end
 
    lua.DebugEx(strLuaDEID, 'WCS任务启动=》出库:查询起点货位', StartLoc)
    --判断有无进行中的移库任务,如果有移库任务未完成,则暂时不出库
    local MoveTask = ""
    local MoveTaskSelect = "S_OP_CODE = '" .. Wcstask.op_code .. "' and N_B_STATE='0' and N_SCHEDULE_TYPE=7"
    nRet, MoveTask = m3.GetDataObjByCondition(strLuaDEID, "Task", MoveTaskSelect)
    if (nRet == 1) then
        lua.DebugEx(strLuaDEID, "获取移库任务:", "移库任务不存在")
        MoveTask = ""
    end
    if (nRet == 2) then
        lua.Stop(strLuaDEID, "获取起点移库信息! SQL条件: " .. MoveTaskSelect)
        return
    end
    if (MoveTask ~= '') then
        lua.DebugEx(strLuaDEID, 'WCS任务启动=》出库:有未执行的移库任务,任务暂不推送', MoveTask)
        return
    end
 
    --判断当前任务是单托任务还是双托任务
    if (Wcstask.groupby == Wcstask.op_code and Wcstask.op_code ~= '') then --任务号等于分组标识,说明是后叉任务 和前叉任务一起推送,不单个推送
        lua.DebugEx(strLuaDEID, 'WCS任务启动=》出库:该任务为后叉任务,和前叉一起推送,暂不推送', Wcstask)
        return
    end
    --获取外侧货位
    local OutStartLoc = nil
    if StartLoc.pos == 2 then
        local OutStartLocSelect = "N_COL=" ..
            StartLoc.col .. " and N_LAYER=" .. StartLoc.layer .. " and N_POS=1"
        nRet, OutStartLoc = m3.GetDataObjByCondition(strLuaDEID, "Location", OutStartLocSelect)
        if (nRet ~= 0) then
            lua.Stop(strLuaDEID, "获取起点外侧货位信息有误! " .. OutStartLoc .. " SQL条件: " .. OutStartLocSelect)
            return
        end
    end
    if (Wcstask.groupby == nil or Wcstask.groupby == '') then --任务分组为空,说明为单托任务推送
        --判断外侧货位是否有托盘, 外侧有未锁的托盘,创建移库任务
        if (OutStartLoc ~= nil and OutStartLoc.cur_num == 1) then
            --有托盘有锁暂不处理
            if (OutStartLoc.lock_state ~= 0) then
                lua.DebugEx(strLuaDEID, 'WCS任务启动=》出库:查询起点外侧货位有锁,暂不处理', OutStartLoc)
                return
            else
                --起点外侧有托盘创建移库任务
                lua.DebugEx(strLuaDEID, 'WCS任务启动=》出库:查询起点外侧货位有托盘,创建移库任务', OutStartLoc)
                CreatMoveTask(strLuaDEID, Wcstask, OutStartLoc);
                return;
            end
        end
 
        --外侧货位没托盘,直接推送任务
        --推送单托任务
        --根据任务巷道判断堆垛机
 
        SendTask(strLuaDEID, Wcstask, nil, 2, 1)
    else
        --任务分组不为空,推送双托任务
        --查找同组任务
        if (Wcstask.groupby == Wcstask.op_code) then --作业号等于分组标识,说明是后叉任务 和前叉任务一起推送,不单个推送
            lua.DebugEx(strLuaDEID, 'WCS任务启动=》出库:该任务为后叉任务,和前叉一起推送,暂不推送', Wcstask)
            return
        else
            --前叉任务查询后叉任务
            local nRet, AfterTask
            local AfterTaskSelect = "S_OP_CODE = '" ..
                Wcstask.groupby .. "' and N_B_STATE='0'"
            nRet, AfterTask = m3.GetDataObjByCondition(strLuaDEID, "Task", AfterTaskSelect)
            if (nRet == 1) then
                lua.DebugEx(strLuaDEID, "后叉任务不存在! " .. AfterTask, " SQL条件: " .. AfterTaskSelect)
            end
            if (nRet == 2) then
                lua.Stop(strLuaDEID, "获取后叉任务信息失败! " .. AfterTask .. " SQL条件: " .. AfterTaskSelect)
                return
            end
            --获取后叉任务起点货位
            local AfterStartLoc = nil
            --内测货位需要判断一下外侧货位是否有货
 
            if StartLoc.pos == 2 then
                local AfterStartLocSelect = "S_CODE = '" .. AfterTask.start_loc_code .. "'"
                nRet, AfterStartLoc = m3.GetDataObjByCondition(strLuaDEID, "Location", AfterStartLocSelect)
                if (nRet ~= 0) then
                    lua.Stop(strLuaDEID,
                        "获取后叉任务起点货位信息有误! " .. AfterStartLoc .. " SQL条件: " .. AfterStartLocSelect)
                    return
                end
 
                local OutAfterStartLocSelect = "N_COL='" ..
                    AfterStartLoc.col .. "' and N_LAYER='" .. AfterStartLoc.layer .. "' and N_POS='1'"
                nRet, AfterStartLoc = m3.GetDataObjByCondition(strLuaDEID, "Location", OutAfterStartLocSelect)
                if (nRet ~= 0) then
                    lua.Stop(strLuaDEID,
                        "获取后叉起点外侧货位信息有误! " .. AfterStartLoc .. " SQL条件: " .. OutAfterStartLocSelect)
                    return
                end
                --后叉外侧货位有托盘
                if (AfterStartLoc ~= nil and AfterStartLoc.cur_num == 1) then
                    --有托盘有锁暂不处理
                    if (AfterStartLoc.locks ~= 0) then
                        --判断外侧货位是否有托盘, 外侧有未锁的托盘,创建移库任务,如果前叉外侧和后叉外侧都存在锁先不处理
                        if (OutStartLoc ~= nil and OutStartLoc.cur_num == 1) then
                            --有托盘有锁暂不处理
                            if (OutStartLoc.lock_state ~= 0) then
                                lua.DebugEx(strLuaDEID, 'WCS任务启动=》出库:查询起点外侧货位有锁,后叉外侧也存在锁,暂不处理',
                                    OutStartLoc)
                                return
                            else
                                --起点外侧有托盘创建移库任务
                                lua.DebugEx(strLuaDEID, 'WCS任务启动=》出库:查询起点外侧货位有托盘,创建移库任务', OutStartLoc)
                                CreatMoveTask(strLuaDEID, Wcstask, OutStartLoc);
                                return;
                            end
                        end
                        return
                    end
                    --后叉外侧需要移库,判断前叉有没有需要移库的货位,如果有则创建一组移库任务
                    --判断外侧货位是否有托盘
                    if (OutStartLoc ~= nil and OutStartLoc.cur_num == 1) then
                        if (OutStartLoc.lock_state ~= 0) then
                            --后叉外侧有托盘,前叉外侧货位有锁
                            lua.DebugEx(strLuaDEID, 'WCS任务启动=》出库:查询起点外侧货位有锁,暂不处理,创建单个移库任务', OutStartLoc)
                            CreatMoveTask(strLuaDEID, AfterTask, OutStartLoc);
                            return;
                        else
                            --后叉外侧货位有托盘,前叉外侧也有托盘,生成分组移库任务
                            CreatMoveTask(strLuaDEID, Wcstask, OutStartLoc, AfterTask.op_name);
                            CreatMoveTask(strLuaDEID, AfterTask, OutStartLoc, AfterTask.op_name);
                        end
                    else
                        --后叉外侧有托盘,前叉外侧没托盘,生成单个移库任务
                        CreatMoveTask(strLuaDEID, AfterTask, OutStartLoc);
                        return;
                    end
                else
                    --后叉外侧没托盘,判断前叉外侧有没有托盘,如果有且没锁,需要创建移库任务
                    --判断外侧货位是否有托盘, 外侧有未锁的托盘,创建移库任务
                    if (OutStartLoc ~= nil and OutStartLoc.cur_num == 1) then
                        --有托盘有锁暂不处理
                        if (OutStartLoc.lock_state ~= 0) then
                            lua.DebugEx(strLuaDEID, 'WCS任务启动=》出库:查询起点外侧货位有锁,暂不处理', OutStartLoc)
                        else
                            --起点外侧有托盘创建移库任务
                            lua.DebugEx(strLuaDEID, 'WCS任务启动=》出库:查询起点外侧货位有托盘,创建移库任务', OutStartLoc)
                            CreatMoveTask(strLuaDEID, Wcstask, OutStartLoc);
                            return;
                        end
                    end
                end
            end
            --推送双托任务
            SendTask(strLuaDEID, Wcstask, AfterTask, 2, 3)
        end
    end
end
--推送堆垛机入库任务
local function SendPutIn(strLuaDEID, Wcstask)
    --判断任务起点终点是否一致,如果起点终点一致,说明是未分配终点任务,暂时不推送
    if (Wcstask.start_loc_code == Wcstask.end_loc_code) then
        lua.DebugEx(strLuaDEID, 'WCS任务启动=》入库:任务' .. Wcstask.code .. '起点终点一致,暂不推送', Wcstask)
        return
    end
    --判断当前任务是单托任务还是双托任务
    if Wcstask.groupby ~= '' then
        if (Wcstask.groupby == Wcstask.op_code) then --作业号等于分组标识,说明是后叉任务 和前叉任务一起推送,不单个推送
            lua.DebugEx(strLuaDEID, 'WCS任务启动=》出库:该任务为后叉任务,和前叉一起推送,暂不推送', Wcstask)
            return
        else
            --前叉任务查询后叉任务一起推送
            local nRet, AfterTask
            local AfterTaskSelect = "S_OP_CODE = '" ..
                Wcstask.groupby .. "' and N_B_STATE='0' and N_TYPE=5 and S_CODE !='" .. Wcstask.code .. "'"
            nRet, AfterTask = m3.GetDataObjByCondition(strLuaDEID, "Task", AfterTaskSelect)
            if (nRet ~= 0) then
                lua.Stop(strLuaDEID, "获取后叉任务信息失败! " .. AfterTask .. " SQL条件: " .. AfterTaskSelect)
                return
            end
            SendTask(strLuaDEID, Wcstask, AfterTask, 1, 3)
        end
    else
        --单托任务直接推送
        SendTask(strLuaDEID, Wcstask, nil, 1, 2)
    end
end
 
--推送堆垛机移库任务
local function SendPutMove(strLuaDEID, Wcstask)
    --判断任务起点终点是否一致,如果起点终点一致,说明是未分配终点任务,暂时不推送
    -- if (Wcstask.start_loc_code == Wcstask.end_loc_code) then
    --     lua.Debug(strLuaDEID, debug.getinfo(1), 'WCS任务启动=》入库:任务' .. Wcstask.code .. '起点终点一致,暂不推送', Wcstask)
    -- end
    --判断当前任务是单托任务还是双托任务
    if Wcstask.groupby ~= nil then
        if (Wcstask.groupby == Wcstask.op_code) then --作业号等于分组标识,说明是后叉任务 和前叉任务一起推送,不单个推送
            lua.DebugEx(strLuaDEID, 'WCS任务启动=》出库:该任务为后叉任务,和前叉一起推送,暂不推送', Wcstask)
            return
        else
            --前叉任务查询后叉任务一起推送
            local nRet, AfterTask
            local AfterTaskSelect = "S_OP_CODE = '" .. Wcstask.groupby .. "' and N_B_STATE=='0' and N_SCHEDULE_TYPE==5"
            nRet, AfterTask = m3.GetDataObjByCondition(strLuaDEID, "Task", AfterTaskSelect)
            if (nRet ~= 0) then
                lua.Stop(strLuaDEID, "获取后叉任务信息失败! " .. AfterTask .. " SQL条件: " .. AfterTaskSelect)
                return
            end
            SendTask(strLuaDEID, AfterTask, nil, 3, 3)
        end
    else
        --单托任务直接推送
        SendTask(strLuaDEID, Wcstask, nil, 3, 1)
    end
end
function WcsTaskRun(strLuaDEID)
    -- 查询任务表全部未推送的作业
    local nRet, WCSTasks
    local strCondition = "N_B_STATE = '0'"
    nRet, WCSTasks = m3.QueryDataObject(strLuaDEID, "Task", strCondition)
    if (nRet ~= 0) then
        lua.Stop(strLuaDEID, "获取未启动的作业错误!" .. WCSTasks)
        return 1
    end
    lua.DebugEx(strLuaDEID, 'WCS作业启动:', WCSTasks)
 
 
    if (WCSTasks ~= '') then
        for i = 1, #WCSTasks do
            local WcsTask
            nRet, WcsTask = m3.ObjAttrStrToLuaObj("Task", lua.table2str(WCSTasks[i].attrs))
            if (nRet ~= 0) then
                lua.Stop(strLuaDEID,
                    "任务信息转换失败! " .. WCSTasks .. " SQL条件: " .. WcsTask)
                return
            end
 
            if (WcsTask.schedule_type == 5 and WcsTask.type == 5) then
                SendPutIn(strLuaDEID, WcsTask)      --堆垛机入库
            elseif (WcsTask.schedule_type == 5 and WcsTask.type == 6) then
                SendPutOut(strLuaDEID, WcsTask)     --堆垛机出库
            elseif (WcsTask.schedule_type == 5 and WcsTask.type == 7) then
                SendPutMove(strLuaDEID, WcsTask)    --堆垛机移库
            elseif (WcsTask.schedule_type == 4 and WcsTask.type == 2) then
                SendPutOutSssx(strLuaDEID, WcsTask) --输送线出库
            elseif (WcsTask.schedule_type == 4 and WcsTask.type == 8) then
                SendEmpty(strLuaDEID, WcsTask)      --输送线空托搬运
            end
        end
    end
 
    return 0
end