using System.Collections.Concurrent; using System.Collections.ObjectModel; using System.Text.Json; using Microsoft.Extensions.Logging; using Seyounth.Hyosung.Core.Agv; using Seyounth.Hyosung.Core.Plc; using Seyounth.Hyosung.Core.Printer; using Seyounth.Hyosung.Core.Scanner; using Seyounth.Hyosung.Data.Models; using Seyounth.Hyosung.Data.Models.Plc; using Seyounth.Hyosung.Data.Services; using Seyounth.Hyosung.Data.Services.Hyosung; using Seyounth.Hyosung.Data.Services.Hyosung.Entities; using Seyounth.Hyosung.Runtime.Models; namespace Seyounth.Hyosung.Runtime; public class HyosungRuntime( ILogger logger, IHyosungPlcService hyosungPlcService, IHyosungScannerService hyosungScannerService, IHyosungPrinter printer, IYarnService yarnService, ITrayService trayService, IVarietyService varietyService, IHyosungAgvService hyosungAgvService, IHyosungWmsService hyosungWmsService, IDictService dictService, IReportExportService reportExportService) : IHyosungRuntime { public PackLineOption PackLineOption { get; private set; } public StackStationModel Stack1 { get; private set; } = new(); public StackStationModel Stack2 { get; private set; } = new(); private ConcurrentQueue _packingQueue = new ConcurrentQueue(); private string currentPrintTrayCode = ""; public async Task StartAsync(CancellationToken token) { reportExportService.ExportNoExportAsync(); //启动扫码服务 await hyosungScannerService.StartAsync(token); await printer.StartAsync(token); //最后启动PLC服务 hyosungPlcService.OnPlcRequestScanProduct += OnPlcRequestScanProduct; hyosungPlcService.OnPlcRequestScanFixture += OnPlcRequestScanFixture; hyosungPlcService.OnPlcRequestLeavingProductionLine += OnPlcRequestLeavingProductionLine; hyosungPlcService.OnPlcNeedNewTrayCode += OnPlcNeedNewTrayCode; hyosungPlcService.OnPlcPutCompleted += OnPlcPutCompleted; hyosungPlcService.OnPlcRequestPackLineOption += OnPlcRequestPackLineOption; hyosungPlcService.OnRequestPrintLabel += OnPlcRequestPrintLabel; hyosungPlcService.OnRequestGetPrintLableOption += OnRequestGetPrintLabel; hyosungPlcService.OnRequestScanEntry += OnPlcRequestScanEntry; await hyosungPlcService.StartAsync(token); } private async Task OnPlcRequestScanEntry(int arg) { logger.LogInformation($"plc request scan entry:{arg}"); try { var carCode = await hyosungScannerService.ScanYarnCarAsync(arg); var varietyId = await hyosungScannerService.ScanVarietyAsync(arg); if (string.IsNullOrEmpty(carCode) || string.IsNullOrEmpty(varietyId)) { await hyosungPlcService.WriteScanEntryResultAsync(arg, false); logger.LogInformation($"scan entry fail"); } else { var carType = carCode[..1]; int carNumber = carType switch { "A" => 1, "B" => 2, "C" => 3, "D" => 4, _ => 0 }; var variety = await varietyService.GetById(int.Parse(varietyId)); variety.YarnCarType = carNumber; variety.YarnCarSide = 1; await SendVarietyToPlcAsync(variety); await hyosungPlcService.WriteScanEntryResultAsync(arg, true); logger.LogInformation($"scan entry success: {carCode}"); } } catch (Exception e) { await hyosungPlcService.WriteScanEntryResultAsync(arg, false); logger.LogError(e, $"scan entry fail"); } } public async Task StopAsync(CancellationToken token) { //先停止扫码服务 await hyosungScannerService.StopAsync(token); await printer.StopAsync(token); //先停止PLC服务 //解绑相关事件 hyosungPlcService.OnPlcRequestScanProduct -= OnPlcRequestScanProduct; hyosungPlcService.OnPlcRequestScanFixture -= OnPlcRequestScanFixture; hyosungPlcService.OnPlcRequestLeavingProductionLine -= OnPlcRequestLeavingProductionLine; hyosungPlcService.OnPlcNeedNewTrayCode -= OnPlcNeedNewTrayCode; hyosungPlcService.OnPlcPutCompleted -= OnPlcPutCompleted; await hyosungPlcService.StopAsync(); } public async Task SendVarietyToPlcAsync(Variety variety) { await hyosungPlcService.WriteVarietyAsync(variety); logger.LogInformation($"send variety to plc success: {variety.Id}"); } public async Task GenerateReportAsync() { var trays = await trayService.GetTodayTrayAsync(); foreach (var tray in trays) { } } /// /// 处理PLC请求扫描治具事件 /// /// 治具ID /// /// private async Task OnPlcRequestScanFixture(int fixtureId) { logger.LogInformation($"plc request scan fixture:{fixtureId}"); try { var fix = await hyosungScannerService.ScanFixtureAsync(fixtureId); if (string.IsNullOrEmpty(fix)) { await hyosungPlcService.WriteScanFixtureResultAsync(fixtureId, false); logger.LogInformation($"scan fixture{fixtureId} fail"); } else { await hyosungPlcService.WriteScanFixtureResultAsync(fixtureId, true, (short)Convert.ToInt32(fix)); logger.LogInformation($"scan fixture{fixtureId} success: {fix}"); } } catch (Exception e) { await hyosungPlcService.WriteScanFixtureResultAsync(fixtureId, false); logger.LogError(e, $"scan fixture{fixtureId} fail"); } } /// /// 处理PLC请求扫描纱事件 /// /// private async Task OnPlcRequestScanProduct(int varietyId) { logger.LogInformation($"plc request scan yarn qrcode"); try { var yarn = await hyosungScannerService.ScanYarnAsync(varietyId); if (yarn is null) { await hyosungPlcService.WriteScanYarnResultAsync(false); logger.LogInformation($"scan yarn fail"); return; } var variety = await varietyService.GetById(varietyId); if (yarn.Lot != variety.Lot) { await hyosungPlcService.WriteScanYarnResultAsync(false); logger.LogInformation($"scan yarn fail,lot not equal"); return; } await yarnService.AddYarnAsync(yarn); await hyosungPlcService.WriteScanYarnResultAsync(true, (short)varietyId, yarn.ScanCode); logger.LogInformation($"scan yarn {yarn.ScanCode} success: qrcode[{yarn.QrCode}]"); } catch (Exception e) { await hyosungPlcService.WriteScanYarnResultAsync(false); logger.LogError(e, $"scan yarn fail"); } } /// /// 处理PLC请求下线事件 /// /// /// private async Task OnPlcRequestLeavingProductionLine(PlcStackInfo info) { logger.LogInformation($"plc request leaving production line"); try { await trayService.StorageAsync(info.TrayCode); reportExportService.ExportSampleAsync(info.TrayCode); await hyosungAgvService.StorageAsync(info.TrayCode); //标志下线已完成 await hyosungPlcService.LeaveCompletedAsync(); logger.LogInformation($"plc leaving production line success"); } catch (Exception e) { logger.LogError(e, $"plc leaving production line fail"); } } /// /// 处理Plc需要新的托盘号事件 /// /// /// /// /// private async Task OnPlcNeedNewTrayCode(int index, int varietyId) { logger.LogInformation($"plc request new tray code:{index} {varietyId}"); try { var tray = await trayService.GeneraNewTray(varietyId); var variety = await varietyService.GetById(varietyId); var stackModel = new StackStationModel(); stackModel.TrayCode = tray.TrayCode; stackModel.VarietyCode = variety.Code; stackModel.Layers = variety.StackingLayers; stackModel.TotalCount = variety.TotalCount; stackModel.CurrentCount = 0; stackModel.Yarns = new ObservableCollection(); if (index == 1) { Stack1 = stackModel; } else { Stack2 = stackModel; } await hyosungPlcService.WriteTrayCodeAsync(index, tray.TrayCode); logger.LogInformation($"plc request new tray code success: {tray.TrayCode}"); } catch (Exception e) { logger.LogError(e, $"plc request new tray code fail"); } } /// /// PLC码垛一次完成 /// /// /// /// private async Task OnPlcPutCompleted(PlcStackingInfo arg) { logger.LogInformation($"plc put completed:{JsonSerializer.Serialize(arg)}"); try { if (arg.TrayCode == Stack1.TrayCode) { Stack1.CurrentCount += arg.YarnCode.Count; foreach (var yarnCode in arg.YarnCode) { Stack1.Yarns.Add(await yarnService.GetYarnByCodeAsync(yarnCode)); } } else if (arg.TrayCode == Stack2.TrayCode) { Stack2.CurrentCount += arg.YarnCode.Count; foreach (var yarnCode in arg.YarnCode) { Stack2.Yarns.Add(await yarnService.GetYarnByCodeAsync(yarnCode)); } } foreach (var yarnCode in arg.YarnCode) { await yarnService.BindTrayAsync(yarnCode, await trayService.GetIdByCode(arg.TrayCode)); logger.LogInformation($" stack yarn{yarnCode} succeed"); } await hyosungPlcService.WriteReceivedYarnCountAsync(arg.YarnCode.Count); logger.LogInformation($"plc put completed success"); } catch (Exception e) { logger.LogError(e, $"plc put completed fail"); } } /// /// 处理PLC请求打包线配置事件 /// /// /// /// private async Task OnPlcRequestPackLineOption(string arg) { logger.LogInformation($"plc request pack line option"); try { var tray = await trayService.GetByCode(arg); var variety = await varietyService.GetById(tray.VarietyId); _packingQueue.Enqueue(variety.Id); var mod = await hyosungWmsService.GetItemInfoByItemCode(variety.Code); var grade = "1"; if (mod.GRADE != "AA") grade = mod.GRADE; var count = _packingQueue.Count(x => x == variety.Id); var control = await varietyService.GetLastNo(variety.Id); if (control is null) control = await hyosungWmsService.GetControlNo(variety, grade); else control = control + 1; if (control == 1000) control = 1; var isEven = control % 2 == 0; await varietyService.SetLastNo(variety.Id, control.Value); await trayService.SetControlNoAsync(arg, control.Value); PackLineOption = new PackLineOption() { HeadCount = variety.StackHeadCount ?? 0, HasBox = variety.HasBox, TrayCode = arg }; if (variety.NeedTopBoard == NeedType.Need || (isEven && variety.NeedTopBoard == NeedType.EvenNeed) || (!isEven && variety.NeedTopBoard == NeedType.OddNeed)) PackLineOption.IsTop = true; else PackLineOption.IsTop = false; if (variety.NeedPackStrap == NeedType.Need || (isEven && variety.NeedPackStrap == NeedType.EvenNeed) || (!isEven && variety.NeedPackStrap == NeedType.OddNeed)) PackLineOption.IsPack = true; else PackLineOption.IsPack = false; if (variety.NeedFilmWrapping == NeedType.Need || (isEven && variety.NeedFilmWrapping == NeedType.EvenNeed) || (!isEven && variety.NeedFilmWrapping == NeedType.OddNeed)) PackLineOption.IsFilm = true; else PackLineOption.IsFilm = false; if (variety.NeedFilmCoating == NeedType.Need || (isEven && variety.NeedFilmCoating == NeedType.EvenNeed) || (!isEven && variety.NeedFilmCoating == NeedType.OddNeed)) PackLineOption.IsLam = true; else PackLineOption.IsLam = false; await hyosungPlcService.WritePackLineOptionAsync(PackLineOption); logger.LogInformation($"plc request pack line option success"); } catch (Exception e) { logger.LogError(e, $"plc request pack line option fail"); } } private async Task OnRequestGetPrintLabel(string arg) { try { logger.LogInformation("request print option"); currentPrintTrayCode = arg; var tray = await trayService.GetByCode(arg); var variety = await varietyService.GetById(tray.VarietyId); var mod = await hyosungWmsService.GetItemInfoByItemCode(variety.Code); // var grade = "1"; // if (mod.GRADE != "AA") grade = mod.GRADE; // int? controlNo; // if (tray.ControlNo is null || tray.ControlNo == 0) // { // controlNo = await varietyService.GetLastNo(variety.Id); // if (controlNo is null) // controlNo = await hyosungWmsService.GetControlNo(variety, grade); // else // controlNo += 1; // // } tray = await trayService.PrintTrayAsync(arg, mod, variety); await dictService.SetValue("System", "CurrentPackingTrayCode", arg); await hyosungPlcService.WritePrintLableOptionsAsync(variety.MasterLabelCount, variety.SubLabelCount); logger.LogInformation("request print option succeed"); } catch(Exception e) { logger.LogError(e, "GetPrintOptionError"); } } /// /// 处理贴标站请求贴标事件 /// /// /// /// /// private async Task OnPlcRequestPrintLabel(int arg1, int height) { var trayCode = await dictService.GetValue("System", "CurrentPackingTrayCode"); var tray = await trayService.GetByCode(trayCode); logger.LogInformation($"plc request print label:{arg1} {tray.TrayCode} {height}"); //var tray = await trayService.GetByCode(currentPrintTrayCode); var variety = await varietyService.GetById(tray.VarietyId); await trayService.UpdateHeightAsync(tray.TrayCode, height); try { if (arg1 == 1) { await printer.PrintAsync(1, tray.TrayCode); await hyosungPlcService.WritePrintLabelResultAsync(arg1, true); } else { await printer.PrintAsync(2, tray.TrayCode); await hyosungPlcService.WritePrintLabelResultAsync(arg1, true); var version=await hyosungWmsService.GetItemInfoByItemCode(variety.Code); // await varietyService.SetLastNo(variety.Id, tray.ControlNo.Value); //await hyosungWmsService.UpdateControlNo(variety, tray.ControlNo.Value); // await hyosungWmsService.AddLabelResult(new LabelResult(tray, variety)); } logger.LogInformation($"plc request print label success"); } catch (Exception e) { await hyosungPlcService.WritePrintLabelResultAsync(arg1, false); logger.LogError(e, "print label fail"); } } }