Commit f8e29d9a13af10b1d5ff43de698811f8c2d5eb1c
1 parent
65782e02
完善站台逻辑,更换同步机制
Showing
1 changed file
with
317 additions
and
209 deletions
HHWCSHost/View/Frm_Main.xaml.cs
... | ... | @@ -22,7 +22,8 @@ namespace HHWCSHost.View |
22 | 22 | { |
23 | 23 | #region 属性 |
24 | 24 | |
25 | - const string plcAdressPrefix = "S7:[S7 connection_1]"; | |
25 | + //const string plcAdressPrefix = "S7:[S7 connection_1]"; | |
26 | + private object locker = new object(); | |
26 | 27 | |
27 | 28 | //所有子窗口 |
28 | 29 | Dictionary<string, Window> windows = new Dictionary<string, Window>(); |
... | ... | @@ -64,7 +65,7 @@ namespace HHWCSHost.View |
64 | 65 | InitTimer(); |
65 | 66 | InitOPC(); |
66 | 67 | InitDeviceData(); |
67 | - InitStockerAndStationMonitor(); | |
68 | + //InitStockerAndStationMonitor(); | |
68 | 69 | } |
69 | 70 | |
70 | 71 | #region 初始化 |
... | ... | @@ -86,28 +87,28 @@ namespace HHWCSHost.View |
86 | 87 | DevicePropEntities = temp3.Data; |
87 | 88 | DeviceTypeEntities = temp4.Data; |
88 | 89 | //属性地址校验 |
89 | - //foreach (var item in DeviceEntities) | |
90 | - //{ | |
91 | - // if (DeviceAddressEntities.Count(t => t.DeviceId == item.Id) == 0) | |
92 | - // { | |
93 | - // String msg = "错误:设备" + item.Code + " " + item.Name + "无属性地址"; | |
94 | - // MessageBox.Show("msg"); | |
95 | - // AddLogToUI(msg, 2); | |
96 | - // btn_OpenPLCConnect.IsEnabled = false; | |
97 | - // return; | |
98 | - // } | |
99 | - // //todo:校验属性是否都存在 | |
100 | - // if (DevicePropEntities.Count(t => t.DeviceTypeId == item.DeviceTypeId) != DeviceAddressEntities.Count(t => t.DeviceId == item.Id)) | |
101 | - // { | |
102 | - // String msg = "错误:设备" + item.Code + " " + item.Name + "属性地址与类型属性规定不一致"; | |
103 | - // MessageBox.Show("msg"); | |
104 | - // AddLogToUI(msg, 2); | |
105 | - // btn_OpenPLCConnect.IsEnabled = false; | |
106 | - // return; | |
107 | - // } | |
108 | - //} | |
90 | + foreach (var item in DeviceEntities) | |
91 | + { | |
92 | + if (DeviceAddressEntities.Count(t => t.DeviceId == item.Id) == 0) | |
93 | + { | |
94 | + String msg = "错误:设备" + item.Code + " " + item.Name + "无属性地址"; | |
95 | + MessageBox.Show("msg"); | |
96 | + AddLogToUI(msg, 2); | |
97 | + btn_OpenPLCConnect.IsEnabled = false; | |
98 | + return; | |
99 | + } | |
100 | + //todo:校验属性是否都存在 | |
101 | + if (DevicePropEntities.Count(t => t.DeviceTypeId == item.DeviceTypeId) != DeviceAddressEntities.Count(t => t.DeviceId == item.Id)) | |
102 | + { | |
103 | + String msg = "错误:设备" + item.Code + " " + item.Name + "属性地址与类型属性规定不一致"; | |
104 | + MessageBox.Show("msg"); | |
105 | + AddLogToUI(msg, 2); | |
106 | + btn_OpenPLCConnect.IsEnabled = false; | |
107 | + return; | |
108 | + } | |
109 | + } | |
109 | 110 | //属性地址获取无误后初始化监控 |
110 | - //InitStockerAndStationMonitor(); | |
111 | + InitStockerAndStationMonitor(); | |
111 | 112 | } |
112 | 113 | |
113 | 114 | private void InitStockerAndStationMonitor() |
... | ... | @@ -164,7 +165,7 @@ namespace HHWCSHost.View |
164 | 165 | try |
165 | 166 | { |
166 | 167 | PLCIP = ConfigurationManager.AppSettings["OPCServerIP"]; |
167 | - PLC = new OPCHelp("192.168.10.100"); | |
168 | + PLC = new OPCHelp(PLCIP); | |
168 | 169 | } |
169 | 170 | catch (Exception ex) |
170 | 171 | { |
... | ... | @@ -266,7 +267,7 @@ namespace HHWCSHost.View |
266 | 267 | for (int i = 0; i < DeviceAddressEntities.Count; i++) |
267 | 268 | { |
268 | 269 | var temp = DeviceAddressEntities[i]; |
269 | - ServerHandle[i] = PLC.AddAddr(plcAdressPrefix + temp.Address, i); | |
270 | + ServerHandle[i] = PLC.AddAddr(temp.Address, i); | |
270 | 271 | temp.ServerHandle = ServerHandle[i]; |
271 | 272 | } |
272 | 273 | } |
... | ... | @@ -309,10 +310,45 @@ namespace HHWCSHost.View |
309 | 310 | private void OnTimedEvent(object sender, ElapsedEventArgs e) |
310 | 311 | { |
311 | 312 | //同步线程防止重入 |
312 | - if (Interlocked.Exchange(ref inTimer, 1) == 0) | |
313 | + //if (Interlocked.Exchange(ref inTimer, 1) == 0) | |
314 | + //{ | |
315 | + lock (locker) | |
313 | 316 | { |
317 | + //AddLogToUI("线程" + Thread.CurrentThread.ManagedThreadId + "进入", 1); | |
318 | + //Thread.Sleep(5000); | |
319 | + //return; | |
320 | + | |
314 | 321 | //todo:完善主控时钟 |
315 | 322 | |
323 | + #region 检查是否连接正常 | |
324 | + if (PLC.GetConnStatus()) | |
325 | + { | |
326 | + this.Dispatcher.Invoke(new Action(() => | |
327 | + { | |
328 | + if (this.grid.Background == Brushes.Red) | |
329 | + { | |
330 | + this.grid.Background = Brushes.White; | |
331 | + } | |
332 | + })); | |
333 | + } | |
334 | + else | |
335 | + { | |
336 | + this.Dispatcher.Invoke(new Action(() => | |
337 | + { | |
338 | + if (this.grid.Background != Brushes.Red) | |
339 | + { | |
340 | + this.grid.Background = Brushes.Red; | |
341 | + } | |
342 | + if (!((TextBlock)this.LogInfo.list_Log.SelectedItem).Text.Contains("失去通讯连接,请关闭连接后重新打开")) | |
343 | + { | |
344 | + this.LogInfo.AddLogs("失去通讯连接,请关闭连接后重新打开", 2); | |
345 | + } | |
346 | + })); | |
347 | + //这里直接retrun,并没有更改inTimer的值,后续不会再次进入这个循环,需要关闭连接然后重新打开连接来重置这个参数; | |
348 | + return; | |
349 | + } | |
350 | + #endregion | |
351 | + | |
316 | 352 | #region 测试监控赋值 |
317 | 353 | |
318 | 354 | InitDeviceData(); |
... | ... | @@ -320,16 +356,16 @@ namespace HHWCSHost.View |
320 | 356 | DeviceEntities.ForEach(item => DeviceAddressEntities.FindAll(t => t.DeviceId == item.Id).Join(DevicePropEntities.FindAll(t => t.DeviceTypeId == item.DeviceTypeId && t.IsMonitor == 1), t => t.DevicePropCode, a => a.Code, (a, b) => new { a, b }).Where(t => t.a.value != t.b.MonitorCompareValue).Select(t => t.b).ToList().ForEach(t => AddLogToUI("报警:" + t.Name + " 信息:" + t.MonitorFailure, 2))); |
321 | 357 | //底部面板 |
322 | 358 | Dispatcher.Invoke(new Action(() => |
359 | + { | |
360 | + foreach (var item in panel_Bottom.Children) | |
361 | + { | |
362 | + if (item is StockerInfo temp) | |
323 | 363 | { |
324 | - foreach (var item in panel_Bottom.Children) | |
325 | - { | |
326 | - if (item is StockerInfo temp) | |
327 | - { | |
328 | - var a = DeviceEntities.Find(t => t.Code == temp.Name); | |
329 | - temp.SetProps(DeviceEntities.Find(t => t.Code == temp.Name), DevicePropEntities.FindAll(t => t.DeviceTypeId == a.DeviceTypeId), DeviceAddressEntities.FindAll(t => t.DeviceId == a.Id)); | |
330 | - } | |
331 | - }; | |
364 | + var a = DeviceEntities.Find(t => t.Code == temp.Name); | |
365 | + temp.SetProps(DeviceEntities.Find(t => t.Code == temp.Name), DevicePropEntities.FindAll(t => t.DeviceTypeId == a.DeviceTypeId), DeviceAddressEntities.FindAll(t => t.DeviceId == a.Id)); | |
332 | 366 | } |
367 | + }; | |
368 | + } | |
333 | 369 | )); |
334 | 370 | //图形监控 |
335 | 371 | Dispatcher.Invoke(new Action(() => |
... | ... | @@ -378,35 +414,6 @@ namespace HHWCSHost.View |
378 | 414 | //return; |
379 | 415 | #endregion |
380 | 416 | |
381 | - #region 检查是否连接正常 | |
382 | - if (PLC.GetConnStatus()) | |
383 | - { | |
384 | - this.Dispatcher.Invoke(new Action(() => | |
385 | - { | |
386 | - if (this.grid.Background == Brushes.Red) | |
387 | - { | |
388 | - this.grid.Background = Brushes.White; | |
389 | - } | |
390 | - })); | |
391 | - } | |
392 | - else | |
393 | - { | |
394 | - this.Dispatcher.Invoke(new Action(() => | |
395 | - { | |
396 | - if (this.grid.Background != Brushes.Red) | |
397 | - { | |
398 | - this.grid.Background = Brushes.Red; | |
399 | - } | |
400 | - if (!((TextBlock)this.LogInfo.list_Log.SelectedItem).Text.Contains("失去通讯连接,请关闭连接后重新打开")) | |
401 | - { | |
402 | - this.LogInfo.AddLogs("失去通讯连接,请关闭连接后重新打开", 2); | |
403 | - } | |
404 | - })); | |
405 | - //这里直接retrun,并没有更改inTimer的值,后续不会再次进入这个循环,需要关闭连接然后重新打开连接来重置这个参数; | |
406 | - return; | |
407 | - } | |
408 | - #endregion | |
409 | - | |
410 | 417 | #region 堆垛机操作 |
411 | 418 | //找出所有堆垛机 |
412 | 419 | var stockersResult = FindDevByType("stocker"); |
... | ... | @@ -438,18 +445,71 @@ namespace HHWCSHost.View |
438 | 445 | var readResult = ReadAddress(addresses); |
439 | 446 | if (readResult.Success) |
440 | 447 | { |
441 | - if (ValidateStationForStockerIn(addresses)) | |
448 | + //if (ValidateStationForStockerIn(addresses)) | |
449 | + //{ | |
450 | + // //查询对应堆垛机是否达到可以入库的状态 | |
451 | + // var stocker = FindDevByType("stocker").Data.Find(t => t.Roadway == stationForStockerIn.Roadway); | |
452 | + // if (stocker != null) | |
453 | + // { | |
454 | + // if (ValidateStockerOut(DeviceAddressEntities.FindAll(t => t.DeviceId == stocker.Id))) | |
455 | + // { | |
456 | + // //todo:下发堆垛机任务,响应站台,待站台逻辑理清后再做处理 | |
457 | + // //待站台逻辑 | |
458 | + | |
459 | + // } | |
460 | + // } | |
461 | + //} | |
462 | + //这里先直接回应一个响应 | |
463 | + //如果PLC标记为3,则表示解析有误,这里报警 | |
464 | + if (addresses.Find(t => t.DevicePropCode == "Flag").value == "3") | |
442 | 465 | { |
443 | - //查询对应堆垛机是否达到可以入库的状态 | |
444 | - var stocker = FindDevByType("stocker").Data.Find(t => t.Roadway == stationForStockerIn.Roadway); | |
445 | - if (stocker != null) | |
466 | + AddLogToUI("PLC解析站台" + stationForStockerIn + "数据失败,请检查基础数据!", 2); | |
467 | + continue; | |
468 | + } | |
469 | + //PLC 有新消息标记 && WCS回复有新消息标记:此时WCS已经回复了消息,等待PLC响应,不做处理,如果PLC新标记为3,表示解析错误 | |
470 | + if (addresses.Find(t => t.DevicePropCode == "Flag").value == "1" && addresses.Find(t => t.DevicePropCode == "WCSFlag").value == "1") | |
471 | + { | |
472 | + continue; | |
473 | + } | |
474 | + //PLC没有新消息标记 && WCS有新消息标记:此时PLC已经确认消息,清除WCS回复消息 | |
475 | + if (addresses.Find(t => t.DevicePropCode == "Flag").value != "1" && addresses.Find(t => t.DevicePropCode == "WCSFlag").value == "1") | |
476 | + { | |
477 | + var result = WriteWCSStationDataAddress(addresses, "0", "0", "0", "0", "0", "0", "", "0", "0"); | |
478 | + if (result.Success) | |
446 | 479 | { |
447 | - if (ValidateStockerOut(DeviceAddressEntities.FindAll(t => t.DeviceId == stocker.Id))) | |
448 | - { | |
449 | - //todo:下发堆垛机任务,响应站台,待站台逻辑理清后再做处理 | |
450 | - //待站台逻辑 | |
480 | + AddLogToUI("清空" + stationForStockerIn + "WCS区地址成功", 1); | |
481 | + } | |
482 | + else | |
483 | + { | |
484 | + AddLogToUI("清空" + stationForStockerIn + "WCS区地址失败:" + result.Msg, 2); | |
485 | + } | |
486 | + continue; | |
487 | + } | |
451 | 488 | |
489 | + //PLC有新消息标记 && WCS没有新消息标记:此时PLC发送了消息而WCS没有响应,写响应逻辑发送地址数据给PLC | |
490 | + if (addresses.Find(t => t.DevicePropCode == "Flag").value == "1" && addresses.Find(t => t.DevicePropCode == "WCSFlag").value != "1") | |
491 | + { | |
492 | + //判断报文类型 | |
493 | + if (addresses.Find(t => t.DevicePropCode == "Type").value == "1") | |
494 | + { | |
495 | + //地址请求 | |
496 | + AddLogToUI("堆垛机接入站台" + stationForStockerIn + "暂时没有实现地址请求", 1); | |
497 | + continue; | |
498 | + } | |
499 | + if (addresses.Find(t => t.DevicePropCode == "Type").value == "2") | |
500 | + { | |
501 | + //给他回一个位置到达 | |
502 | + //响应一个位置请求 | |
503 | + var temp = WriteWCSStationDataAddress(addresses, "1", "8", addresses.Find(t => t.DevicePropCode == "PLCNo").value, "0", addresses.Find(t => t.DevicePropCode == "StationNo").value, addresses.Find(t => t.DevicePropCode == "TaskNo").value, addresses.Find(t => t.DevicePropCode == "Barcode").value, "", "0"); | |
504 | + if (temp.Success) | |
505 | + { | |
506 | + AddLogToUI("位置到达写入" + stationForStockerIn + "WCS区地址成功", 1); | |
452 | 507 | } |
508 | + else | |
509 | + { | |
510 | + AddLogToUI("位置到达写入" + stationForStockerIn + "WCS区地址失败:" + temp.Msg, 2); | |
511 | + } | |
512 | + continue; | |
453 | 513 | } |
454 | 514 | } |
455 | 515 | } |
... | ... | @@ -489,35 +549,7 @@ namespace HHWCSHost.View |
489 | 549 | //PLC没有新消息标记 && WCS有新消息标记:此时PLC已经确认消息,清除WCS回复消息 |
490 | 550 | if (addresses.Find(t => t.DevicePropCode == "Flag").value != "1" && addresses.Find(t => t.DevicePropCode == "WCSFlag").value == "1") |
491 | 551 | { |
492 | - List<DeviceAddressEntity> temp = new List<DeviceAddressEntity>(); | |
493 | - var wcsflag = addresses.Find(t => t.DevicePropCode == "WCSFlag"); | |
494 | - wcsflag.value = "0"; | |
495 | - var wcstype = addresses.Find(t => t.DevicePropCode == "WCSType"); | |
496 | - wcstype.value = "0"; | |
497 | - var wcsplcno = addresses.Find(t => t.DevicePropCode == "WCSPLCNo"); | |
498 | - wcsplcno.value = "0"; | |
499 | - var wcsloadstatus = addresses.Find(t => t.DevicePropCode == "LoadStatus"); | |
500 | - wcsloadstatus.value = "0"; | |
501 | - var wcsstationno = addresses.Find(t => t.DevicePropCode == "WCSStationNo"); | |
502 | - wcsstationno.value = "0"; | |
503 | - var wcstaskno = addresses.Find(t => t.DevicePropCode == "WCSTaskNo"); | |
504 | - wcstaskno.value = "0"; | |
505 | - var wcsbarcode = addresses.Find(t => t.DevicePropCode == "WCSBarcode"); | |
506 | - wcsbarcode.value = ""; | |
507 | - var wcstoaddress = addresses.Find(t => t.DevicePropCode == "WCSToAddress"); | |
508 | - wcstoaddress.value = "0"; | |
509 | - var wcsbackup = addresses.Find(t => t.DevicePropCode == "WCSBackUp"); | |
510 | - wcsbackup.value = "0"; | |
511 | - temp.Add(wcsflag); | |
512 | - temp.Add(wcstype); | |
513 | - temp.Add(wcsplcno); | |
514 | - temp.Add(wcsloadstatus); | |
515 | - temp.Add(wcsstationno); | |
516 | - temp.Add(wcstaskno); | |
517 | - temp.Add(wcsbarcode); | |
518 | - temp.Add(wcstoaddress); | |
519 | - temp.Add(wcsbackup); | |
520 | - var result = WriteAddress(temp); | |
552 | + var result = WriteWCSStationDataAddress(addresses, "0", "0", "0", "0", "0", "0", "", "0", "0"); | |
521 | 553 | if (result.Success) |
522 | 554 | { |
523 | 555 | AddLogToUI("清空" + stationForStockerOut + "WCS区地址成功", 1); |
... | ... | @@ -543,35 +575,7 @@ namespace HHWCSHost.View |
543 | 575 | if (station != null) |
544 | 576 | { |
545 | 577 | //写入响应数据 |
546 | - List<DeviceAddressEntity> temp = new List<DeviceAddressEntity>(); | |
547 | - var wcsflag = addresses.Find(t => t.DevicePropCode == "WCSFlag"); | |
548 | - wcsflag.value = "1"; | |
549 | - var wcstype = addresses.Find(t => t.DevicePropCode == "WCSType"); | |
550 | - wcstype.value = "6"; | |
551 | - var wcsplcno = addresses.Find(t => t.DevicePropCode == "WCSPLCNo"); | |
552 | - wcsplcno.value = addresses.Find(t => t.DevicePropCode == "PLCNo").value; | |
553 | - var wcsloadstatus = addresses.Find(t => t.DevicePropCode == "LoadStatus"); | |
554 | - wcsloadstatus.value = "0"; | |
555 | - var wcsstationno = addresses.Find(t => t.DevicePropCode == "WCSStationNo"); | |
556 | - wcsstationno.value = addresses.Find(t => t.DevicePropCode == "StationNo").value; | |
557 | - var wcstaskno = addresses.Find(t => t.DevicePropCode == "WCSTaskNo"); | |
558 | - wcstaskno.value = addresses.Find(t => t.DevicePropCode == "TaskNo").value; | |
559 | - var wcsbarcode = addresses.Find(t => t.DevicePropCode == "WCSBarcode"); | |
560 | - wcsbarcode.value = addresses.Find(t => t.DevicePropCode == "Barcode").value; | |
561 | - var wcstoaddress = addresses.Find(t => t.DevicePropCode == "WCSToAddress"); | |
562 | - wcstoaddress.value = station.SelfAddress.ToString(); | |
563 | - var wcsbackup = addresses.Find(t => t.DevicePropCode == "WCSBackUp"); | |
564 | - wcsbackup.value = "0"; | |
565 | - temp.Add(wcsflag); | |
566 | - temp.Add(wcstype); | |
567 | - temp.Add(wcsplcno); | |
568 | - temp.Add(wcsloadstatus); | |
569 | - temp.Add(wcsstationno); | |
570 | - temp.Add(wcstaskno); | |
571 | - temp.Add(wcsbarcode); | |
572 | - temp.Add(wcstoaddress); | |
573 | - temp.Add(wcsbackup); | |
574 | - var result = WriteAddress(temp); | |
578 | + var result = WriteWCSStationDataAddress(addresses, "1", "6", addresses.Find(t => t.DevicePropCode == "PLCNo").value, "0", addresses.Find(t => t.DevicePropCode == "StationNo").value, addresses.Find(t => t.DevicePropCode == "TaskNo").value, addresses.Find(t => t.DevicePropCode == "Barcode").value, station.SelfAddress.ToString(), "0"); | |
575 | 579 | if (result.Success) |
576 | 580 | { |
577 | 581 | AddLogToUI("写入" + stationForStockerOut + "WCS区地址成功", 1); |
... | ... | @@ -585,7 +589,6 @@ namespace HHWCSHost.View |
585 | 589 | { |
586 | 590 | AddLogToUI("未找到出库站台", 2); |
587 | 591 | } |
588 | - | |
589 | 592 | } |
590 | 593 | //hack:出库对位置到达和控制指令如何回复? |
591 | 594 | |
... | ... | @@ -628,35 +631,7 @@ namespace HHWCSHost.View |
628 | 631 | //PLC没有新消息标记 && WCS有新消息标记:此时PLC已经确认消息,清除WCS回复消息 |
629 | 632 | if (addresses.Find(t => t.DevicePropCode == "Flag").value != "1" && addresses.Find(t => t.DevicePropCode == "WCSFlag").value == "1") |
630 | 633 | { |
631 | - List<DeviceAddressEntity> temp = new List<DeviceAddressEntity>(); | |
632 | - var wcsflag = addresses.Find(t => t.DevicePropCode == "WCSFlag"); | |
633 | - wcsflag.value = "0"; | |
634 | - var wcstype = addresses.Find(t => t.DevicePropCode == "WCSType"); | |
635 | - wcstype.value = "0"; | |
636 | - var wcsplcno = addresses.Find(t => t.DevicePropCode == "WCSPLCNo"); | |
637 | - wcsplcno.value = "0"; | |
638 | - var wcsloadstatus = addresses.Find(t => t.DevicePropCode == "LoadStatus"); | |
639 | - wcsloadstatus.value = "0"; | |
640 | - var wcsstationno = addresses.Find(t => t.DevicePropCode == "WCSStationNo"); | |
641 | - wcsstationno.value = "0"; | |
642 | - var wcstaskno = addresses.Find(t => t.DevicePropCode == "WCSTaskNo"); | |
643 | - wcstaskno.value = "0"; | |
644 | - var wcsbarcode = addresses.Find(t => t.DevicePropCode == "WCSBarcode"); | |
645 | - wcsbarcode.value = ""; | |
646 | - var wcstoaddress = addresses.Find(t => t.DevicePropCode == "WCSToAddress"); | |
647 | - wcstoaddress.value = "0"; | |
648 | - var wcsbackup = addresses.Find(t => t.DevicePropCode == "WCSBackUp"); | |
649 | - wcsbackup.value = "0"; | |
650 | - temp.Add(wcsflag); | |
651 | - temp.Add(wcstype); | |
652 | - temp.Add(wcsplcno); | |
653 | - temp.Add(wcsloadstatus); | |
654 | - temp.Add(wcsstationno); | |
655 | - temp.Add(wcstaskno); | |
656 | - temp.Add(wcsbarcode); | |
657 | - temp.Add(wcstoaddress); | |
658 | - temp.Add(wcsbackup); | |
659 | - var result = WriteAddress(temp); | |
634 | + var result = WriteWCSStationDataAddress(addresses, "0", "0", "0", "0", "0", "0", "", "0", "0"); | |
660 | 635 | if (result.Success) |
661 | 636 | { |
662 | 637 | AddLogToUI("清空" + station + "WCS区地址成功", 1); |
... | ... | @@ -668,12 +643,11 @@ namespace HHWCSHost.View |
668 | 643 | continue; |
669 | 644 | } |
670 | 645 | |
671 | - | |
672 | 646 | //PLC有新消息标记 && WCS没有新消息标记:此时PLC发送了消息而WCS没有响应,写响应逻辑发送地址数据给PLC |
673 | 647 | if (addresses.Find(t => t.DevicePropCode == "Flag").value == "1" && addresses.Find(t => t.DevicePropCode == "WCSFlag").value != "1") |
674 | 648 | { |
675 | 649 | //获取任务 |
676 | - string pallet = addresses.Find(t => t.DevicePropCode == "").value; | |
650 | + string pallet = addresses.Find(t => t.DevicePropCode == "Barcode").value; | |
677 | 651 | var taskResult = Bll.GetTaskUncompleteByPalletCode(pallet); |
678 | 652 | if (!taskResult.Success) |
679 | 653 | { |
... | ... | @@ -681,8 +655,6 @@ namespace HHWCSHost.View |
681 | 655 | continue; |
682 | 656 | } |
683 | 657 | TaskEntity taskEntity = taskResult.Data; |
684 | - //string pallet = addresses.Find(t => t.DevicePropCode == "").value; | |
685 | - //var taskResult = Bll.GetTaskUncompleteByPalletCode(pallet); | |
686 | 658 | //判断报文类型 |
687 | 659 | if (addresses.Find(t => t.DevicePropCode == "Type").value == "1") |
688 | 660 | { |
... | ... | @@ -694,27 +666,97 @@ namespace HHWCSHost.View |
694 | 666 | var locationResult = Bll.GetAllLocations(null, null, null, null, null, null, taskEntity.DestinationLocation); |
695 | 667 | if (!locationResult.Success) |
696 | 668 | { |
697 | - AddLogToUI("未找到任务" + taskEntity.Id + "对应的"+taskEntity.DestinationLocation+"库位",2); | |
669 | + AddLogToUI("未找到任务" + taskEntity.Id + "对应的" + taskEntity.DestinationLocation + "库位", 2); | |
670 | + continue; | |
671 | + } | |
672 | + location = locationResult.Data[0]; | |
673 | + } | |
674 | + else if (taskEntity.Type == 200 || taskEntity.Type == 400 || taskEntity.Type == 700) | |
675 | + { | |
676 | + var locationResult = Bll.GetAllLocations(null, null, null, null, null, null, taskEntity.SourceLocation); | |
677 | + if (!locationResult.Success) | |
678 | + { | |
679 | + AddLogToUI("未找到任务" + taskEntity.Id + "对应的" + taskEntity.SourceLocation + "库位", 2); | |
698 | 680 | continue; |
699 | 681 | } |
700 | 682 | location = locationResult.Data[0]; |
701 | 683 | } |
702 | - if(taskEntity.Type == 200 || taskEntity.Type == 400 || taskEntity.Type == 700) | |
684 | + else | |
685 | + { | |
686 | + AddLogToUI("任务" + taskEntity.Id + "对应的类型" + taskEntity.Type + "不符合地址请求要求", 2); | |
687 | + continue; | |
688 | + } | |
689 | + //获取这个库位的目标巷道,从而得出对应的接入站台 | |
690 | + var stockerStationIns = DeviceEntities.Join(DeviceTypeEntities, t => t.DeviceTypeId, a => a.Id, (a, b) => new { a, b }).Where(t => t.b.Code == "stationForStockerIn" && t.a.Roadway == location.Roadway).Select(t => t.a).ToList(); | |
691 | + if (stockerStationIns.Count == 0) | |
703 | 692 | { |
704 | - // | |
693 | + AddLogToUI("未找到任务" + taskEntity.Id + "对应的堆垛机接入站台,巷道:" + location.Roadway + ",托盘:" + taskEntity.ContainerCode, 2); | |
694 | + continue; | |
695 | + } | |
696 | + else | |
697 | + { | |
698 | + var stockerStationIn = stockerStationIns[0]; | |
699 | + //写入响应地址 | |
700 | + var result = WriteWCSStationDataAddress(addresses, "1", "06", addresses.Find(t => t.DevicePropCode == "PLCNo").value, "0", addresses.Find(t => t.DevicePropCode == "StationNo").value, addresses.Find(t => t.DevicePropCode == "TaskNo").value, addresses.Find(t => t.DevicePropCode == "Barcode").value, stockerStationIn.SelfAddress.ToString(), "0"); | |
701 | + if (result.Success) | |
702 | + { | |
703 | + AddLogToUI("写入" + stockerStationIn + "WCS区地址成功", 1); | |
704 | + } | |
705 | + else | |
706 | + { | |
707 | + AddLogToUI("写入" + stockerStationIn + "WCS区地址失败:" + result.Msg, 2); | |
708 | + } | |
705 | 709 | } |
706 | 710 | } |
707 | 711 | |
708 | 712 | if (addresses.Find(t => t.DevicePropCode == "Type").value == "2") |
709 | 713 | { |
710 | - //表示位置到达,此时检查任务,如果是整出则完成任务 | |
711 | - | |
714 | + //表示位置到达,此时检查任务,如果是整出、空出则完成任务 | |
715 | + if (taskEntity.Type == 300 || taskEntity.Type == 600) | |
716 | + { | |
717 | + var result = Bll.CompleteTask(taskEntity.Id.ToString()); | |
718 | + if (result.Success) | |
719 | + { | |
720 | + AddLogToUI("站台" + station + ",完成" + taskEntity.Id.ToString() + "成功", 1); | |
721 | + } | |
722 | + else | |
723 | + { | |
724 | + AddLogToUI("完成任务" + taskEntity.Id.ToString() + "失败:" + result.Msg, 2); | |
725 | + continue; | |
726 | + } | |
727 | + } | |
728 | + else | |
729 | + { | |
730 | + //如果是其他类型的任务则更新状态为到达站台并响应 | |
731 | + var result = Bll.SetTaskStatus(taskEntity.Id, 30); | |
732 | + if (result.Success) | |
733 | + { | |
734 | + AddLogToUI("站台" + station + ",更新任务状态" + taskEntity.Id.ToString() + "成功", 1); | |
735 | + } | |
736 | + else | |
737 | + { | |
738 | + AddLogToUI("站台" + station + ",更新任务状态" + taskEntity.Id.ToString() + "失败:" + result.Msg, 2); | |
739 | + continue; | |
740 | + } | |
741 | + } | |
742 | + //响应一个位置请求 | |
743 | + var temp = WriteWCSStationDataAddress(addresses, "1", "8", addresses.Find(t => t.DevicePropCode == "PLCNo").value, "0", addresses.Find(t => t.DevicePropCode == "StationNo").value, addresses.Find(t => t.DevicePropCode == "TaskNo").value, addresses.Find(t => t.DevicePropCode == "Barcode").value, "", "0"); | |
744 | + if (temp.Success) | |
745 | + { | |
746 | + AddLogToUI("位置到达写入" + station + "WCS区地址成功", 1); | |
747 | + } | |
748 | + else | |
749 | + { | |
750 | + AddLogToUI("位置到达写入" + station + "WCS区地址失败:" + temp.Msg, 2); | |
751 | + } | |
752 | + continue; | |
712 | 753 | } |
713 | 754 | |
714 | 755 | if (addresses.Find(t => t.DevicePropCode == "Type").value == "3") |
715 | 756 | { |
716 | 757 | //表示控制指令 |
717 | 758 | //todo:控制指令先不弄 |
759 | + AddLogToUI("控制指令暂时没有实现", 1); | |
718 | 760 | } |
719 | 761 | |
720 | 762 | } |
... | ... | @@ -727,9 +769,9 @@ namespace HHWCSHost.View |
727 | 769 | } |
728 | 770 | |
729 | 771 | #endregion |
730 | - | |
731 | - Interlocked.Exchange(ref inTimer, 0); | |
732 | 772 | } |
773 | + //Interlocked.Exchange(ref inTimer, 0); | |
774 | + //} | |
733 | 775 | } |
734 | 776 | |
735 | 777 | #region 功能函数 |
... | ... | @@ -753,34 +795,42 @@ namespace HHWCSHost.View |
753 | 795 | foreach (var stocker in stockers) |
754 | 796 | { |
755 | 797 | var propDatas = DeviceAddressEntities.FindAll(t => t.DeviceId == stocker.Id); |
756 | - if (ReadAddress(propDatas) && ValidateStockerForCompleteTask(stocker)) | |
798 | + var result = ReadAddress(propDatas); | |
799 | + if (result.Success) | |
757 | 800 | { |
758 | - //现获取要写入的数据的转换后类型,如果转换出错就不进行处理 | |
759 | - BllResult writeDataResult = TansforWCSDataToAddressData(DevicePropEntities.Find(t => t.DeviceTypeId == stocker.DeviceTypeId && t.Code == "TaskNo1").Type, "0"); | |
760 | - if (!writeDataResult.Success) | |
761 | - { | |
762 | - AddLogToUI(writeDataResult.Msg, 2); | |
763 | - break; | |
764 | - } | |
765 | - //获取任务号 | |
766 | - var writeData = writeDataResult.Data; | |
767 | - var propData = propDatas.Find(t => t.DevicePropCode == "TaskNo1"); | |
768 | - var taskCompleteResult = Bll.CompleteTask(propData.value); | |
769 | - if (taskCompleteResult.Success) | |
801 | + if (ValidateStockerForCompleteTask(stocker)) | |
770 | 802 | { |
771 | - //任务完成成功:任务执行完成后由PLC向WCS发送任务完成消息,WCS清除任务信息,随后PLC更新堆垛机状态为待机 | |
772 | - //清除任务 | |
773 | - bool writeFlag = PLC.WriteData(new int[] { propData.ServerHandle }, new object[] { writeData }); | |
774 | - if (!writeFlag) | |
803 | + //现获取要写入的数据的转换后类型,如果转换出错就不进行处理 | |
804 | + BllResult writeDataResult = TansforWCSDataToAddressData(DevicePropEntities.Find(t => t.DeviceTypeId == stocker.DeviceTypeId && t.Code == "TaskNo1").Type, "0"); | |
805 | + if (!writeDataResult.Success) | |
775 | 806 | { |
776 | - AddLogToUI("完成任务" + propData.value + "成功,但是清除堆垛机" + stocker.ToString() + "任务失败", 2); | |
807 | + AddLogToUI(writeDataResult.Msg, 2); | |
808 | + break; | |
809 | + } | |
810 | + //获取任务号 | |
811 | + var writeData = writeDataResult.Data; | |
812 | + var propData = propDatas.Find(t => t.DevicePropCode == "TaskNo1"); | |
813 | + var taskCompleteResult = Bll.CompleteTask(propData.value); | |
814 | + if (taskCompleteResult.Success) | |
815 | + { | |
816 | + //任务完成成功:任务执行完成后由PLC向WCS发送任务完成消息,WCS清除任务信息,随后PLC更新堆垛机状态为待机 | |
817 | + //清除任务 | |
818 | + bool writeFlag = PLC.WriteData(new int[] { propData.ServerHandle }, new object[] { writeData }); | |
819 | + if (!writeFlag) | |
820 | + { | |
821 | + AddLogToUI("完成任务" + propData.value + "成功,但是清除堆垛机" + stocker.ToString() + "任务失败", 2); | |
822 | + } | |
823 | + } | |
824 | + else | |
825 | + { | |
826 | + AddLogToUI("任务" + propData.value + " 堆垛机" + stocker.ToString() + "完成任务失败:" + taskCompleteResult.Msg, 2); | |
777 | 827 | } |
778 | - } | |
779 | - else | |
780 | - { | |
781 | - AddLogToUI("任务" + propData.value + " 堆垛机" + stocker.ToString() + "完成任务失败:" + taskCompleteResult.Msg, 2); | |
782 | 828 | } |
783 | 829 | } |
830 | + else | |
831 | + { | |
832 | + AddLogToUI("读取" + stocker + "地址数据失败:" + result.Msg, 2); | |
833 | + } | |
784 | 834 | } |
785 | 835 | } |
786 | 836 | |
... | ... | @@ -884,35 +934,43 @@ namespace HHWCSHost.View |
884 | 934 | //地址校验交由初始化完成 |
885 | 935 | var props = DeviceAddressEntities.Where(t => t.DeviceId == stocker.Id).ToList(); |
886 | 936 | //堆垛机出库任务校验 |
887 | - if (ReadAddress(props) && ValidateStockerOut(props)) | |
937 | + var result = ReadAddress(props); | |
938 | + if (result.Success) | |
888 | 939 | { |
889 | - //校验对应堆垛机接出站台是否可以,按巷道查询 | |
890 | - var stationForStockerOutResult = FindDevByType("stationForStockerOut"); | |
891 | - if (stationForStockerOutResult.Success) | |
940 | + if (ValidateStockerOut(props)) | |
892 | 941 | { |
893 | - var stationForStockerOuts = stationForStockerOutResult.Data.FindAll(t => t.Roadway == location.Roadway); | |
894 | - foreach (var stationForStockerOut in stationForStockerOuts) | |
942 | + //校验对应堆垛机接出站台是否可以,按巷道查询 | |
943 | + var stationForStockerOutResult = FindDevByType("stationForStockerOut"); | |
944 | + if (stationForStockerOutResult.Success) | |
895 | 945 | { |
896 | - //校验接出站台是否可用 | |
897 | - if (ValidateStationForStockerOut(stationForStockerOut)) | |
946 | + var stationForStockerOuts = stationForStockerOutResult.Data.FindAll(t => t.Roadway == location.Roadway); | |
947 | + foreach (var stationForStockerOut in stationForStockerOuts) | |
898 | 948 | { |
899 | - if (stationForStockerOut.SelfAddress != -1) | |
949 | + //校验接出站台是否可用 | |
950 | + if (ValidateStationForStockerOut(stationForStockerOut)) | |
900 | 951 | { |
901 | - //可用,下发任务 | |
902 | - BllResult sendResult = SendTaskToStocker(stocker, stationForStockerOut, task); | |
903 | - if (!BllResult.Success) | |
952 | + if (stationForStockerOut.SelfAddress != -1) | |
904 | 953 | { |
905 | - AddLogToUI("堆垛机" + stocker.ToString() + "下发任务失败:" + sendResult.Msg, 2); | |
954 | + //可用,下发任务 | |
955 | + BllResult sendResult = SendTaskToStocker(stocker, stationForStockerOut, task); | |
956 | + if (!BllResult.Success) | |
957 | + { | |
958 | + AddLogToUI("堆垛机" + stocker.ToString() + "下发任务失败:" + sendResult.Msg, 2); | |
959 | + } | |
960 | + } | |
961 | + else | |
962 | + { | |
963 | + AddLogToUI("堆垛机" + stocker.ToString() + "接出站台没有配置自身地址数据", 2); | |
906 | 964 | } |
907 | - } | |
908 | - else | |
909 | - { | |
910 | - AddLogToUI("堆垛机" + stocker.ToString() + "接出站台没有配置自身地址数据", 2); | |
911 | 965 | } |
912 | 966 | } |
913 | 967 | } |
914 | 968 | } |
915 | 969 | } |
970 | + else | |
971 | + { | |
972 | + AddLogToUI("读取" + stocker + "地址数据失败", 2); | |
973 | + } | |
916 | 974 | } |
917 | 975 | } |
918 | 976 | |
... | ... | @@ -955,6 +1013,11 @@ namespace HHWCSHost.View |
955 | 1013 | throw new NotImplementedException(); |
956 | 1014 | } |
957 | 1015 | |
1016 | + /// <summary> | |
1017 | + /// 添加界面日志,1绿色,2红色 | |
1018 | + /// </summary> | |
1019 | + /// <param name="log"></param> | |
1020 | + /// <param name="level"></param> | |
958 | 1021 | private void AddLogToUI(string log, int level) |
959 | 1022 | { |
960 | 1023 | this.Dispatcher.Invoke(new Action(() => |
... | ... | @@ -1041,6 +1104,51 @@ namespace HHWCSHost.View |
1041 | 1104 | } |
1042 | 1105 | |
1043 | 1106 | /// <summary> |
1107 | + /// 写入WCS站台区地址 | |
1108 | + /// </summary> | |
1109 | + /// <param name="addresses"></param> | |
1110 | + /// <param name="flag"></param> | |
1111 | + /// <param name="type"></param> | |
1112 | + /// <param name="loadstatus"></param> | |
1113 | + /// <param name="stationno"></param> | |
1114 | + /// <param name="taskno"></param> | |
1115 | + /// <param name="barcode"></param> | |
1116 | + /// <param name="backup"></param> | |
1117 | + /// <returns></returns> | |
1118 | + private BllResult WriteWCSStationDataAddress(List<DeviceAddressEntity> addresses, string flag, string type, string plcno, string loadstatus, string stationno, string taskno, string barcode, string toaddress, string backup) | |
1119 | + { | |
1120 | + List<DeviceAddressEntity> temp = new List<DeviceAddressEntity>(); | |
1121 | + var wcsflag = addresses.Find(t => t.DevicePropCode == "WCSFlag"); | |
1122 | + wcsflag.value = flag; | |
1123 | + var wcstype = addresses.Find(t => t.DevicePropCode == "WCSType"); | |
1124 | + wcstype.value = type; | |
1125 | + var wcsplcno = addresses.Find(t => t.DevicePropCode == "WCSPLCNo"); | |
1126 | + wcsplcno.value = plcno; | |
1127 | + var wcsloadstatus = addresses.Find(t => t.DevicePropCode == "LoadStatus"); | |
1128 | + wcsloadstatus.value = loadstatus; | |
1129 | + var wcsstationno = addresses.Find(t => t.DevicePropCode == "WCSStationNo"); | |
1130 | + wcsstationno.value = stationno; | |
1131 | + var wcstaskno = addresses.Find(t => t.DevicePropCode == "WCSTaskNo"); | |
1132 | + wcstaskno.value = taskno; | |
1133 | + var wcsbarcode = addresses.Find(t => t.DevicePropCode == "WCSBarcode"); | |
1134 | + wcsbarcode.value = barcode; | |
1135 | + var wcstoaddress = addresses.Find(t => t.DevicePropCode == "WCSToAddress"); | |
1136 | + wcstoaddress.value = toaddress; | |
1137 | + var wcsbackup = addresses.Find(t => t.DevicePropCode == "WCSBackUp"); | |
1138 | + wcsbackup.value = backup; | |
1139 | + temp.Add(wcsflag); | |
1140 | + temp.Add(wcstype); | |
1141 | + temp.Add(wcsplcno); | |
1142 | + temp.Add(wcsloadstatus); | |
1143 | + temp.Add(wcsstationno); | |
1144 | + temp.Add(wcstaskno); | |
1145 | + temp.Add(wcsbarcode); | |
1146 | + temp.Add(wcstoaddress); | |
1147 | + temp.Add(wcsbackup); | |
1148 | + return WriteAddress(temp); | |
1149 | + } | |
1150 | + | |
1151 | + /// <summary> | |
1044 | 1152 | /// 堆垛机出库任务校验 |
1045 | 1153 | /// 堆垛机接收任务(入库、出库、拣选、转库)条件: |
1046 | 1154 | ///1. 工作模式=2 联机; |
... | ... |