439 lines
17 KiB
C#

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<HyosungRuntime> 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<int> _packingQueue = new ConcurrentQueue<int>();
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)
{
}
}
/// <summary>
/// 处理PLC请求扫描治具事件
/// </summary>
/// <param name="fixtureId">治具ID</param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
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");
}
}
/// <summary>
/// 处理PLC请求扫描纱事件
/// </summary>
/// <param name="varietyId"></param>
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");
}
}
/// <summary>
/// 处理PLC请求下线事件
/// </summary>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
private async Task OnPlcRequestLeavingProductionLine(PlcStackInfo info)
{
logger.LogInformation($"plc request leaving production line");
try
{
await trayService.StorageAsync(info.TrayCode);
await hyosungAgvService.StorageAsync(info.TrayCode);
//标志下线已完成
await hyosungPlcService.LeaveCompletedAsync();
await reportExportService.ExportSampleAsync(info.TrayCode);
logger.LogInformation($"plc leaving production line success");
}
catch (Exception e)
{
logger.LogError(e, $"plc leaving production line fail");
}
}
/// <summary>
/// 处理Plc需要新的托盘号事件
/// </summary>
/// <param name="index"></param>
/// <param name="varietyId"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
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<Yarn>();
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");
}
}
/// <summary>
/// PLC码垛一次完成
/// </summary>
/// <param name="arg"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
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");
}
}
/// <summary>
/// 处理PLC请求打包线配置事件
/// </summary>
/// <param name="arg"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
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");
}
}
/// <summary>
/// 处理贴标站请求贴标事件
/// </summary>
/// <param name="arg1"></param>
/// <param name="arg2"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
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");
}
}
}