using System.Text.Json; using MCProtocol; using Microsoft.Extensions.Logging; using Seyounth.Hyosung.Data.Models; using Seyounth.Hyosung.Data.Models.Plc; namespace Seyounth.Hyosung.Core.Plc; public class HyosungPlcService(ILogger logger) : IHyosungPlcService { private readonly McPlc _reader = new("192.168.3.10", 4060, Mitsubishi.McFrame.MC3E); private readonly McPlc _writer = new("192.168.3.10", 4061, Mitsubishi.McFrame.MC3E); private bool isLeaving = false; public async Task StartAsync(CancellationToken token) { List> ls = [ _reader.ConnectAsync(), _writer.ConnectAsync() ]; var codes = await Task.WhenAll(ls); logger.LogInformation($"plc reader connect code: {codes[0]}\r\nplc writer connect code: {codes[1]}"); ReadLoop(token); } public async Task StopAsync() { List> ls = [ _reader.CloseAsync(), _writer.CloseAsync() ]; var codes = await Task.WhenAll(ls); logger.LogInformation($"plc reader close code: {codes[0]}\r\nplc writer close code: {codes[1]}"); } public async Task WriteVarietyAsync(Variety variety) { var data = variety.ToVarietyPlcData(); await _writer.WriteShortsAsync(4200, data); logger.LogInformation($"write [{string.Join(",", data)}] data to plc address[4200]"); await _writer.WriteShortsAsync(4230, (short)variety.Id); logger.LogInformation($"write [{variety.Id}] to plc address[4230]"); } public async Task WriteScanYarnResultAsync(bool result, short? varietyId = null, string? yarnCode = null) { if (result && yarnCode != null && varietyId != null) { await _writer.WriteShortsAsync(4009, varietyId.Value); await _writer.WriteStringAsync(4010, yarnCode); logger.LogInformation($"write [{yarnCode}] to plc address[4010]"); } await _writer.WriteShortsAsync(4000, (short)(result ? 1 : 2)); logger.LogInformation($"write [{(result ? 1 : 2)}] to plc address[4000]"); } public async Task WriteScanFixtureResultAsync(int fixtureId, bool result, short? fixtureCode = null) { int flagAddress = 4000 + fixtureId; int codeAddress = 4004 + fixtureId; if (result && fixtureCode != null) { await _writer.WriteShortsAsync(codeAddress, fixtureCode.Value); logger.LogInformation($"write [{fixtureCode}] to plc address[{codeAddress}]"); } await _writer.WriteShortsAsync(flagAddress, (short)(result ? 1 : 2)); logger.LogInformation($"write [{(result ? 1 : 2)}] to plc address[{flagAddress}]"); } public async Task LeaveCompletedAsync() { await _writer.WriteShortsAsync(4020, 0); await _writer.WriteShortsAsync(13012, 0); await _writer.WriteShortsAsync(4520, 1); isLeaving = false; } public async Task WriteTrayCodeAsync(int index, string trayCode) { var address = index == 1 ? 4100 : 4110; await _writer.WriteStringAsync(address, trayCode); } public async Task WriteReceivedYarnCountAsync(int count) { await _writer.WriteShortsAsync(4120, (short)count); } public async Task WritePackLineOptionAsync(PackLineOption option) { List ls = new List(); ls.Add((short)option.HeadCount); ls.Add((short)(option.IsTop ? 1 : 2)); ls.Add(1); ls.Add((short)(option.HasBox ? 1 : 2)); ls.Add((short)(option.IsPack ? 1 : 2)); ls.Add((short)(option.IsFilm ? 1 : 2)); ls.Add((short)(option.IsLam ? 1 : 2)); await _writer.WriteShortsAsync(12120, ls.ToArray()); } public async Task WritePrintLableOptionsAsync(int side, int slave) { short masterCount = 0; switch (side) { case 0: masterCount = 1; break; case 1: masterCount = 2; break; case 2: masterCount = 6; break; case 3: masterCount = 14; break; case 4: masterCount = 30; break; } short slaveCount = 0; switch (slave) { case 0: slaveCount = 1; break; case 1: slaveCount = 2; break; case 2: slaveCount = 6; break; case 3: slaveCount = 14; break; case 4: slaveCount = 30; break; } await _writer.WriteShortsAsync(13050, [1, 1, 1, 2]); } public async Task WritePrintLabelResultAsync(int index, bool result) { var address = index == 1 ? 13060 : 13061; await _writer.WriteShortsAsync(address, (short)(result ? 1 : 2)); } public async Task WriteScanEntryResultAsync(int index, bool result) { var address = index == 1 ? 4530 : 4531; await _writer.WriteShortsAsync(address, (short)(result ? 1 : 2)); } //static byte SetBit(byte value, int bitPosition) //{ // // 创建一个掩码,该掩码只有第 bitPosition 位为 1 // byte mask = (byte)(1 << bitPosition); // // 使用按位或操作将 value 的第 bitPosition 位置为 1 // return (byte)(value | mask); //} public event Func? OnPlcRequestScanProduct; public event Func? OnPlcRequestScanFixture; public event Func? OnPlcRequestLeavingProductionLine; public event Func? OnPlcNeedNewTrayCode; public event Func? OnPlcPutCompleted; public event Func? OnPlcRequestPackLineOption; public event Func? OnRequestPrintLabel; public event Func OnRequestGetPrintLableOption; public event Func? OnRequestScanEntry; private async Task ReadLoop(CancellationToken token) { while (!token.IsCancellationRequested) { try { await QueryScanEntry(); await QueryScanProductRequest(); await QueryScanFixtureRequest(); if (!isLeaving) await QueryLeavingProductionLine(); await QueryNeedTrayCode(); await QueryPutOnceCompleted(); await QueryPackLineOption(); await QueryPrintLabel(); await Task.Delay(100, token); await QueryGetPrintLabel(); } catch (Exception e) { } } } /// /// 查询请求扫描产品方法 /// private async Task QueryScanProductRequest() { var requestScanProduct = await _reader.ReadShortsAsync(4500, 2); if (requestScanProduct[0] == 1) { await _writer.WriteShortsAsync(4500, 0, 0); OnPlcRequestScanProduct?.Invoke(requestScanProduct[1]); } } /// /// 查询扫描夹具请求 /// private async Task QueryScanFixtureRequest() { var requestScanFixture = await _reader.ReadShortsAsync(4505, 4); if (requestScanFixture[0] == 1) { await _writer.WriteShortsAsync(4505, 0); OnPlcRequestScanFixture?.Invoke(1); } if (requestScanFixture[1] == 1) { await _writer.WriteShortsAsync(4506, 0); OnPlcRequestScanFixture?.Invoke(2); } if (requestScanFixture[2] == 1) { await _writer.WriteShortsAsync(4507, 0); await OnPlcRequestScanFixture?.Invoke(3); } if (requestScanFixture[3] == 1) { await _writer.WriteShortsAsync(4508, 0); await OnPlcRequestScanFixture?.Invoke(4); } } /// /// 查询有托盘请求下线 /// private async Task QueryLeavingProductionLine() { var leavingProductionLine = await _reader.ReadShortsAsync(4020, 1); // var stackStatus = await _reader.ReadShortsAsync(12110, 1); if (leavingProductionLine[0] == 1) { var trayCode = await _reader.ReadStringAsync(12600); //if (!string.IsNullOrEmpty(trayCode)) //{ PlcStackInfo info = new PlcStackInfo() { TrayCode = trayCode }; isLeaving = true; OnPlcRequestLeavingProductionLine?.Invoke(info); // } } } /// /// 查询是否需要新的托盘号 /// private async Task QueryNeedTrayCode() { var n1 = await _reader.ReadShortsAsync(4600, 2); var n2 = await _reader.ReadShortsAsync(4610, 2); if (n1[0] == 1) { await _writer.WriteShortsAsync(4600, 0); OnPlcNeedNewTrayCode?.Invoke(1, n1[1]); } if (n2[0] == 1) { await _writer.WriteShortsAsync(4610, 0); OnPlcNeedNewTrayCode?.Invoke(2, n2[1]); } } private async Task QueryPutOnceCompleted() { var status = await _reader.ReadShortsAsync(4691, 2); if (status[0] > 0) { logger.LogInformation($"request put yarn completed"); await _writer.WriteShortsAsync(4690, 0, 0, 0); var trayCode = await _reader.ReadStringAsync(4620); var yarn1 = await _reader.ReadStringAsync(4630); var yarn2 = await _reader.ReadStringAsync(4640); var yarn3 = await _reader.ReadStringAsync(4650); var info = new PlcStackingInfo() { TrayCode = trayCode, YarnCount = status[0], TotalYarnCount = status[1] }; logger.LogInformation($"request put yarn get info: {JsonSerializer.Serialize(info)}"); if (!string.IsNullOrEmpty(yarn1)) info.YarnCode.Add(yarn1); if (!string.IsNullOrEmpty(yarn2)) info.YarnCode.Add(yarn2); if (!string.IsNullOrEmpty(yarn3)) info.YarnCode.Add(yarn3); if (info.YarnCode.Count != info.YarnCount) { logger.LogWarning($"get yarn code count[{info.YarnCode.Count}]不等于YarnCount[{info.TotalYarnCount}]"); return; } await _writer.WriteShortsAsync(4620, new short[40]); OnPlcPutCompleted?.Invoke(info); } } /// /// 打包线请求获取配置 /// private async Task QueryPackLineOption() { var requestPackLineOption = await _reader.ReadShortsAsync(4022, 1); if (requestPackLineOption[0] == 1) { var trayCode = await _reader.ReadStringAsync(12100); await _writer.WriteShortsAsync(4022, 0); OnPlcRequestPackLineOption?.Invoke(trayCode); } } private async Task QueryScanEntry() { var requestScanEntry = await _reader.ReadShortsAsync(4030, 2); if (requestScanEntry[0] == 1) { await _writer.WriteShortsAsync(4030, 0); OnRequestScanEntry?.Invoke(1); } else if (requestScanEntry[1] == 1) { await _writer.WriteShortsAsync(4030, 0); OnRequestScanEntry?.Invoke(2); } } private async Task QueryGetPrintLabel() { var trayCode = await _reader.ReadStringAsync(13000); if (!string.IsNullOrEmpty(trayCode) && !trayCode.StartsWith("0000")) { await _reader.WriteStringAsync(13000, "00000000000000000000"); OnRequestGetPrintLableOption?.Invoke(trayCode); } } private async Task QueryPrintLabel() { var requestPrintLabel = await _reader.ReadShortsAsync(13010, 3); if (requestPrintLabel[0] == 1) { await _writer.WriteShortsAsync(13010, 0); await _writer.WriteShortsAsync(13012, 0); OnRequestPrintLabel?.Invoke(1, requestPrintLabel[2]); } if (requestPrintLabel[1] == 1) { await _writer.WriteShortsAsync(13011, 0); await _writer.WriteShortsAsync(13012, 0); OnRequestPrintLabel?.Invoke(2, requestPrintLabel[2]); } } }