InquiryShelfBean.java
16.0 KB
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
package com.myproject.bean.qisda;
import com.myproject.bean.update.DataLog;
import com.myproject.bean.update.qisda.OutItem;
import com.myproject.util.StorageConstants;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
*
* 出库需求单使用料架情况
* Created by sunke on 2019/12/15.
*/
public class InquiryShelfBean {
protected final static Logger log = LogManager.getLogger(InquiryShelfBean.class);
/**
* 料架管理Map, key为 hSerial, value的key为 tempRfid, value为料架
*/
public static Map<String,Map<String,ShelfInfo>> hSerialShelfMap = new ConcurrentHashMap<>();
/**
* 添加限制库位(即库位中只能放入某个条码)
* @param task
* @param outItem
* @return
*/
public static DataLog addLimitLoc(DataLog task, OutItem outItem){
return addLoc(task, outItem, task.getBarcode());
}
/**
* 首盘料时,缺料站位空出一个架位
*/
public static void addEmptyLoc(OutItem outItem, String shelfType){
String hSerial = outItem.gethSerial();
ShelfInfo emptyShelfInfo = getOrAddShelfInfo(hSerial,shelfType);
if(emptyShelfInfo != null){
int loc = emptyShelfInfo.addEmptyLoc();
log.info("工单"+outItem.getSo()+"["+outItem.getSlotlocation()+"]"+outItem.getPn()+"预留架位"+emptyShelfInfo.tempRfid()+"["+ loc +"]");
updateShelfInfo(emptyShelfInfo);
}
}
/**
* 添加不限制的库位,即库位对条码不作限制
* @param task
* @param outItem
* @return
*/
public static DataLog addUnlimitLoc(DataLog task, OutItem outItem){
return addLoc(task, outItem, "");
}
public static String getShelfType(DataLog task){
//空位预留
if(task == null){
//根据尺寸确定预留种架位
return StorageConstants.SHEFL_TYPE.D;
}
String shelfType = "";
//包装料架
if(task.isPackageReel()){
shelfType = StorageConstants.SHEFL_TYPE.A;
}else {
//需要分盘的料,且不是包装料,统一都放到料串上
if(task.isCutReel() || task.isUrgentReel()){
//B料串
return StorageConstants.SHEFL_TYPE.B;
}else{
if(task.isSmallReel()){
//D料架
shelfType = StorageConstants.SHEFL_TYPE.D;
}else{
shelfType = StorageConstants.SHEFL_TYPE.C;
}
}
}
return shelfType;
}
/**
* 获取未达最大数量的料架,或者添加一个新的料架
* @param shelfType
* @return
*/
private static ShelfInfo getOrAddShelfInfo(String hSerial, String shelfType){
Map<String, ShelfInfo> shelfMap = hSerialShelfMap.get(hSerial);
int rfidIndex = 0;
if(shelfMap != null){
for (ShelfInfo shelfInfo : shelfMap.values()) {
if(StorageConstants.SHEFL_TYPE.judgeType(shelfInfo.getShelfType(), shelfType)){
if(shelfInfo != null && !shelfInfo.reachMaxLoc()){
return shelfInfo;
}
}
}
rfidIndex = shelfMap.size();
}
ShelfInfo newShelf = null;
if(StorageConstants.SHEFL_TYPE.isAShelf(shelfType)){
newShelf = ShelfInfo.newAShelf();
}else if(StorageConstants.SHEFL_TYPE.isBShelf(shelfType)){
newShelf = ShelfInfo.newBShelf();
}if(StorageConstants.SHEFL_TYPE.isCShelf(shelfType)){
newShelf = ShelfInfo.newCShelf();
}else if(StorageConstants.SHEFL_TYPE.isDShelf(shelfType)){
newShelf = ShelfInfo.newDShelf();
}
if(newShelf != null){
newShelf.setRfidIndex(rfidIndex);
newShelf.sethSerial(hSerial);
log.info("添加新料架["+newShelf.tempRfid() + "]");
updateShelfInfo(newShelf);
}
return newShelf;
}
/**
* 更新料架缓存信息
*/
public static void updateShelfInfo(ShelfInfo shelfInfo){
String hSerial = shelfInfo.gethSerial();
Map<String, ShelfInfo> shelfMap = hSerialShelfMap.get(hSerial);
if(shelfMap == null){
shelfMap = new ConcurrentHashMap<>();
}
shelfMap.put(shelfInfo.tempRfid(), shelfInfo);
hSerialShelfMap.put(hSerial, shelfMap);
}
private static synchronized DataLog addLoc(DataLog task, OutItem outItem, String barcode){
String shelfType = getShelfType(task);
String hSerial = outItem.gethSerial();
ShelfInfo emptyShelfInfo = getOrAddShelfInfo(hSerial,shelfType);
if(emptyShelfInfo != null){
if(task != null){
int loc = -1;
AppendInfo appendInfo = task.getAppendInfo();
if(task.isPackageReel()){
//包装料,固定库位
loc = emptyShelfInfo.addLimitLoc(task.getBarcode(),task.getReelType());
appendInfo.setRfidLoc(loc);
}else{
loc = emptyShelfInfo.addLimitLoc(barcode,task.getReelType());
}
log.info("工单"+outItem.getSo()+"["+outItem.getSlotlocation()+"]"+outItem.getPn()+"为["+task.getBarcode()+"]添加架位["+emptyShelfInfo.tempRfid() + "]["+ loc +"]=" + barcode);
appendInfo.setRfidIndex(emptyShelfInfo.getRfidIndex());
appendInfo.setShelfType(shelfType);
appendInfo.sethSerial(hSerial);
if(barcode != null && !barcode.isEmpty()){
appendInfo.setRfidLoc(loc);
}
task.setAppendInfo(appendInfo);
//包装料需要在C型料架上预留位置
if(task.isPackageReel()){
String cShelf = StorageConstants.SHEFL_TYPE.C;
ShelfInfo packageCShelf = getOrAddShelfInfo(hSerial, cShelf);
int packageCLoc = packageCShelf.addLimitLoc(barcode, StorageConstants.REEL_TYPE.PACKAGE);
log.info("包装料预留C型料架:工单"+outItem.getSo()+"["+outItem.getSlotlocation()+"]"+outItem.getPn()+"添加架位["+emptyShelfInfo.tempRfid() + "]["+ packageCLoc +"]=["+packageCShelf.tempRfid() + "]["+ loc +"]=" + barcode);
}
}else{
int loc = emptyShelfInfo.addEmptyLoc();
log.info("工单"+outItem.getSo()+"["+outItem.getSlotlocation()+"]"+outItem.getPn()+"预留架位"+emptyShelfInfo.tempRfid()+"["+ loc +"]");
}
updateShelfInfo(emptyShelfInfo);
}
return task;
}
/**
* 根据tempRfid编号获取料架信息
*/
public ShelfInfo findSameShelf(String hSerial, String rfid){
if(hSerial != null){
Map<String, ShelfInfo> shelfMap = hSerialShelfMap.get(hSerial);
if(shelfMap != null){
for (ShelfInfo shelf : shelfMap.values()) {
String shelfRFID = shelf.getRealRfid();
log.info(shelf.tempRfid() + "判断料架["+shelfRFID+"] = " + rfid);
if(shelfRFID != null && rfid != null){
if(shelfRFID.equals(rfid)){
//已经绑定过该Temp料架
return shelf;
}
}
}
}else{
log.error("未找到需求单["+hSerial+"]料架["+rfid+"], 当前Map:" + hSerialShelfMap);
}
}
return null;
}
/**
* 3号机器人放入时查找大料架,如果没有相同RFID,查找未绑定的相同类型料架
* @param bigRfid
* @return
*/
public ShelfInfo findBigShelf(String bigRfid){
if(bigRfid == null){
return null;
}
ShelfInfo maxLocShelf = null;
for (Map<String, ShelfInfo> shelfInfoMap : hSerialShelfMap.values()) {
for (ShelfInfo shelf : shelfInfoMap.values()) {
String shelfRFID = shelf.getRealRfid();
if(StorageConstants.SHEFL_TYPE.judgeType(bigRfid, shelf.getShelfType())){
if(shelfRFID != null){
if(shelfRFID.equals(bigRfid)){
//已经绑定过该Temp料架
return shelf;
}
}else{
//未绑定过的
if(maxLocShelf == null){
maxLocShelf = shelf;
}else if(shelf.getUsedLocCount() > maxLocShelf.getUsedLocCount()){
maxLocShelf = shelf;
}
}
}
}
}
return maxLocShelf;
}
/**
* 3号机器人放入时查找包装料架上的物料信息(肯定会存在)
* @param packageRfid
* @return
*/
public ShelfInfo findPackageShelf(String packageRfid){
if(packageRfid == null){
return null;
}
for (Map<String, ShelfInfo> shelfInfoMap : hSerialShelfMap.values()) {
for (ShelfInfo shelf : shelfInfoMap.values()) {
String shelfRFID = shelf.getRealRfid();
if(shelfRFID != null){
if(shelfRFID.equals(packageRfid)){
//已经绑定过该Temp料架
return shelf;
}
}
}
}
return null;
}
/**
* 首套料,获取分配好的库位
*/
public ShelfLoc getLimitLoc(DataLog task){
AppendInfo appendInfo = task.getAppendInfo();
String barcode = task.getBarcode();
String hSerial = appendInfo.gethSerial();
Map<String, ShelfInfo> shelfMap = hSerialShelfMap.get(hSerial);
if(shelfMap != null){
for (ShelfInfo shelfInfo : shelfMap.values()) {
int loc = shelfInfo.getBarcodeLoc(barcode, appendInfo.getShelfType());
if(loc != -1){
ShelfLoc shelfLoc = new ShelfLoc();
shelfLoc.setLoc(loc);
shelfLoc.setTempRfid(shelfInfo.tempRfid());
shelfLoc.setRealRfid(shelfInfo.getRealRfid());
log.info("查找到["+barcode+"]分配的库位" + shelfInfo.tempRfid()+"["+loc+"] Task库位"+appendInfo.getRfid()+"["+appendInfo.getRfidLoc()+"]");
return shelfLoc;
}
}
}
return null;
}
/**
* 锁定架位
*/
public synchronized ShelfLoc lockShelfLoc(DataLog task, String rfid, String robotIndex){
AppendInfo appendInfo = task.getAppendInfo();
String hSerial = appendInfo.gethSerial();
ShelfInfo shelfInfo = null;
if(hSerial != null){
Map<String, ShelfInfo> shelfMap = hSerialShelfMap.get(hSerial);
if(shelfMap != null){
//先判断任务料架是否与双层线上的实际料架类型是否一致,如果不一致,直接使用新的料架
if(rfid != null && !rfid.isEmpty()){
if(StorageConstants.SHEFL_TYPE.judgeType(rfid, task.getAppendInfo().getShelfType())){
//任务与当前料架一致,使用已经绑定过的料架
shelfInfo = findSameShelf(hSerial, rfid);
}
}
if(shelfInfo != null){
//找到与实际料架相同的料架,但料架上已经满了,查找其他同类型料架
if(shelfInfo.isFull()){
log.info("料架["+shelfInfo.getRealRfid()+"]="+shelfInfo.tempRfid()+"已满,查找新的料架");
shelfInfo = null;
}
}
//未找到已经有实际RFID的料架,查找库位最多的料架
if(shelfInfo == null){
log.info(task.getBarcode() + "未找到实际绑定的["+rfid+"]料架,开始查找库位最多的同种料架["+task.getAppendInfo().getShelfType()+"]");
ShelfInfo maxLocShelf = null;
for (ShelfInfo shelf : shelfMap.values()) {
if(StorageConstants.SHEFL_TYPE.judgeType(task.getAppendInfo().getShelfType(), shelf.getShelfType())){
//同一种料架
if(maxLocShelf == null){
maxLocShelf = shelf;
}
if(shelf.getUsedLocCount() > maxLocShelf.getUsedLocCount()){
maxLocShelf = shelf;
}
}
}
shelfInfo = maxLocShelf;
if(shelfInfo != null){
log.info(task.getBarcode() + "["+ appendInfo.getTempRfid()+"]未找到rfid=["+rfid+"]的空料架,使用库位最多的同种料架["+shelfInfo.tempRfid()+"]");
}else{
log.info("已没有与["+rfid+"]类型相同的料架");;
}
}
}
}
if(shelfInfo == null){
log.error("任务条码["+task.getBarcode()+"]未找到对应的料架" + rfid);
return null;
}
ShelfLoc lockLoc = shelfInfo.lockOneEmptyLoc(task.getBarcode(), task.getReelType(), robotIndex);
if(lockLoc != null){
log.info("为["+task.getBarcode()+"]锁定架位:" + shelfInfo.tempRfid() + "[" +shelfInfo.getRealRfid()+"]["+lockLoc.getLoc()+"]原来分配架位:" + appendInfo.getTempRfid() + "[" + appendInfo.getRfidLoc() + "]");
// ShelfLoc shelfLoc = new ShelfLoc();
// shelfLoc.setLoc(lockLoc);
// shelfLoc.setRfid(rfid);
if(shelfInfo.getRealRfid() == null || shelfInfo.getRealRfid().isEmpty()){
//未绑定过的,使用TempRFID
lockLoc.setTempRfid(shelfInfo.tempRfid());
lockLoc.setRealRfid("");
}else{
//绑定过的使用RealRfid
lockLoc.setRealRfid(shelfInfo.getRealRfid());
lockLoc.setTempRfid("");
}
updateShelfInfo(shelfInfo);
return lockLoc;
}
return null;
}
public synchronized boolean putInShelf(DataLog task, String rfid, int loc){
AppendInfo appendInfo = task.getAppendInfo();
String barcode = task.getBarcode();
String hSerial = appendInfo.gethSerial();
Map<String, ShelfInfo> shelfMap = hSerialShelfMap.get(hSerial);
if(shelfMap != null){
if(appendInfo.isFirstReelAction()){
//首盘料,要按位置放
for (ShelfInfo shelfInfo : shelfMap.values()) {
boolean putInResult = shelfInfo.putInLimitLoc(rfid,loc, barcode);
if(putInResult){
updateShelfInfo(shelfInfo);
log.info("首盘料["+task.getBarcode()+"]更新料架" + rfid +"["+loc+"]缓存成功");
return true;
}
}
}else{
//非首盘
for (ShelfInfo shelfInfo : shelfMap.values()) {
boolean putInResult = shelfInfo.putInLoc(rfid,loc, barcode);
if(putInResult){
updateShelfInfo(shelfInfo);
log.info("物料["+task.getBarcode()+"]更新料架" + rfid +"["+loc+"]缓存成功");
return true;
}
}
}
}else{
log.info("未找到["+hSerial+"]相关料架");
}
log.error("物料["+task.getBarcode()+"]("+task.getAppendInfo().getTempRfid()+"["+task.getAppendInfo().getRfidLoc()+"])更新料架" + rfid +"["+loc+"]缓存失败");
return false;
}
}