BUG修复

This commit is contained in:
zhangzhuo 2025-03-23 13:09:36 +08:00
parent a84cfd5e71
commit 714ea9a94e
24 changed files with 357 additions and 143 deletions

View File

@ -1,6 +1,7 @@
using System.Net.Http.Json; using System.Net.Http.Json;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Seyounth.Hyosung.Core.Agv.HikModels; using Seyounth.Hyosung.Core.Agv.HikModels;
using Seyounth.Hyosung.Data.Entities;
namespace Seyounth.Hyosung.Core.Agv; namespace Seyounth.Hyosung.Core.Agv;
@ -70,13 +71,40 @@ public class HikAgv(ILogger<HikAgv> logger)
if (rs.Code != "0") if (rs.Code != "0")
{ {
logger.LogWarning($"{start.PositionCode} carry to {end.PositionCode} error: code is {rs.Code}"); logger.LogWarning($"{start.PositionCode} carry to {end.PositionCode} error: code is {rs.Code} message is {rs.Message}");
return; return;
} }
logger.LogInformation($"{start.PositionCode} carry to {end.PositionCode} succeed"); logger.LogInformation($"{start.PositionCode} carry to {end.PositionCode} succeed");
} }
public async Task UnBin(AgvBinEntity bin)
{
var url = Url + "bindCtnrAndBin";
var input = new
{
reqCode = GetRequestCode(),
stgBinCode = bin.CtnrCode,
ctnrTyp = bin.HeightCode,
indBind = "0"
};
var rs = await PostAsync<string>(url, input);
if (rs is null)
{
logger.LogWarning($"agv unbin {bin.CtnrCode} error: result is null");
return;
}
if (rs.Code != "0")
{
logger.LogWarning($"agv unbin {bin.CtnrCode} error: code is {rs.Code} message:{rs.Message}");
return;
}
logger.LogInformation($"agv unbin {bin.CtnrCode} succeed");
}
public async Task MovingToAsync(AgvPosition des, string taskType) public async Task MovingToAsync(AgvPosition des, string taskType)
{ {
var url = Url + SchedulingTaskUri; var url = Url + SchedulingTaskUri;

View File

@ -1,5 +1,6 @@
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Seyounth.Hyosung.Core.Agv.HikModels; using Seyounth.Hyosung.Core.Agv.HikModels;
using Seyounth.Hyosung.Data.Entities;
using Seyounth.Hyosung.Data.Services; using Seyounth.Hyosung.Data.Services;
namespace Seyounth.Hyosung.Core.Agv; namespace Seyounth.Hyosung.Core.Agv;
@ -23,7 +24,7 @@ public class HyosungAgvService(
} while (status is null); } while (status is null);
var tray = await trayService.GetByCode(trayCode); var tray = await trayService.GetByCode(trayCode);
var height = (int)Math.Ceiling((double)(tray.StackHeight / 10.0)!); var height = (int)Math.Ceiling((double)((tray.StackHeight??0) / 10.0)!);
var bin = await agvBinService.GetAvailableBin(height); var bin = await agvBinService.GetAvailableBin(height);
AgvPosition start = new AgvPosition() AgvPosition start = new AgvPosition()
{ {
@ -35,8 +36,21 @@ public class HyosungAgvService(
PositionCode = bin.CtnrCode, PositionCode = bin.CtnrCode,
Type = "05" Type = "05"
}; };
if(!string.IsNullOrEmpty(bin.HeightCode))
await UnBin(bin);
var ctnrType = await dictService.GetKeyAsync("AgvRackType", bin.Height.ToString()); var ctnrType = await dictService.GetKeyAsync("AgvRackType", bin.Height.ToString());
if (string.IsNullOrEmpty(ctnrType))
ctnrType = "14";
bin.HeightCode = ctnrType;
await _agv.CarryToAsync(start, stop, ctnrType, 120, "1"); await _agv.CarryToAsync(start, stop, ctnrType, 120, "1");
await agvBinService.BindAsync(bin); await agvBinService.BindAsync(bin);
//等待30秒 确保AGV已经把产品叉出
await Task.Delay(30 * 1000);
}
public async Task UnBin(AgvBinEntity bin)
{
await _agv.UnBin(bin);
} }
} }

View File

@ -1,3 +1,5 @@
using Seyounth.Hyosung.Data.Entities;
namespace Seyounth.Hyosung.Core.Agv; namespace Seyounth.Hyosung.Core.Agv;
public interface IHyosungAgvService public interface IHyosungAgvService
@ -8,4 +10,6 @@ public interface IHyosungAgvService
/// <param name="trayCode"></param> /// <param name="trayCode"></param>
/// <returns></returns> /// <returns></returns>
Task StorageAsync(string trayCode); Task StorageAsync(string trayCode);
Task UnBin(AgvBinEntity bin);
} }

View File

@ -1,3 +1,4 @@
using System.Text.Json;
using MCProtocol; using MCProtocol;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Seyounth.Hyosung.Data.Models; using Seyounth.Hyosung.Data.Models;
@ -74,7 +75,7 @@ public class HyosungPlcService(ILogger<HyosungPlcService> logger) : IHyosungPlcS
} }
public async Task LeaveCompletedAsync() public async Task LeaveCompletedAsync()
{ {
await _writer.WriteShortsAsync(4020, 0); await _writer.WriteShortsAsync(4020, 0);
await _writer.WriteShortsAsync(13012, 0); await _writer.WriteShortsAsync(13012, 0);
await _writer.WriteShortsAsync(4520, 1); await _writer.WriteShortsAsync(4520, 1);
@ -105,32 +106,32 @@ public class HyosungPlcService(ILogger<HyosungPlcService> logger) : IHyosungPlcS
await _writer.WriteShortsAsync(12120, ls.ToArray()); await _writer.WriteShortsAsync(12120, ls.ToArray());
} }
public async Task WritePrintLabelResultAsync(int index, int side, bool result) public async Task WritePrintLableOptionsAsync(int side)
{
short data = 0;
switch (side)
{
case 0:
data = 1;
break;
case 1:
data = 2;
break;
case 2:
data = 6;
break;
case 3:
data = 14;
break;
case 4:
data = 30;
break;
}
await _writer.WriteShortsAsync(13050, [1, 1, 1, 2]);
}
public async Task WritePrintLabelResultAsync(int index, bool result)
{ {
var address = index == 1 ? 13060 : 13061; var address = index == 1 ? 13060 : 13061;
if (index == 2)
{
short data = 0;
switch (side)
{
case 0:
data = 1;
break;
case 1:
data = 2;
break;
case 2:
data = 6;
break;
case 3:
data = 14;
break;
case 4:
data = 30;
break;
}
await _writer.WriteShortsAsync(13050, [1,1,1, data] );
}
await _writer.WriteShortsAsync(address, (short)(result ? 1 : 2)); await _writer.WriteShortsAsync(address, (short)(result ? 1 : 2));
} }
@ -166,8 +167,8 @@ public class HyosungPlcService(ILogger<HyosungPlcService> logger) : IHyosungPlcS
{ {
await QueryScanProductRequest(); await QueryScanProductRequest();
await QueryScanFixtureRequest(); await QueryScanFixtureRequest();
if (!isLeaving) if(!isLeaving)
await QueryLeavingProductionLine(); await QueryLeavingProductionLine();
await QueryNeedTrayCode(); await QueryNeedTrayCode();
await QueryPutOnceCompleted(); await QueryPutOnceCompleted();
await QueryPackLineOption(); await QueryPackLineOption();
@ -234,17 +235,17 @@ public class HyosungPlcService(ILogger<HyosungPlcService> logger) : IHyosungPlcS
// var stackStatus = await _reader.ReadShortsAsync(12110, 1); // var stackStatus = await _reader.ReadShortsAsync(12110, 1);
if (leavingProductionLine[0] == 1) if (leavingProductionLine[0] == 1)
{ {
await _writer.WriteShortsAsync(4020, 0);
var trayCode = await _reader.ReadStringAsync(12600); var trayCode = await _reader.ReadStringAsync(12600);
if (!string.IsNullOrEmpty(trayCode)) //if (!string.IsNullOrEmpty(trayCode))
{ //{
PlcStackInfo info = new PlcStackInfo() PlcStackInfo info = new PlcStackInfo()
{ {
TrayCode = trayCode TrayCode = trayCode
}; };
isLeaving = true; isLeaving = true;
OnPlcRequestLeavingProductionLine?.Invoke(info); OnPlcRequestLeavingProductionLine?.Invoke(info);
} // }
} }
} }
@ -273,6 +274,7 @@ public class HyosungPlcService(ILogger<HyosungPlcService> logger) : IHyosungPlcS
var status = await _reader.ReadShortsAsync(4691, 2); var status = await _reader.ReadShortsAsync(4691, 2);
if (status[0] > 0) if (status[0] > 0)
{ {
logger.LogInformation($"request put yarn completed");
await _writer.WriteShortsAsync(4690, 0, 0, 0); await _writer.WriteShortsAsync(4690, 0, 0, 0);
var trayCode = await _reader.ReadStringAsync(4620); var trayCode = await _reader.ReadStringAsync(4620);
var yarn1 = await _reader.ReadStringAsync(4630); var yarn1 = await _reader.ReadStringAsync(4630);
@ -284,6 +286,7 @@ public class HyosungPlcService(ILogger<HyosungPlcService> logger) : IHyosungPlcS
YarnCount = status[0], YarnCount = status[0],
TotalYarnCount = status[1] TotalYarnCount = status[1]
}; };
logger.LogInformation($"request put yarn get info: {JsonSerializer.Serialize(info)}");
if (!string.IsNullOrEmpty(yarn1)) if (!string.IsNullOrEmpty(yarn1))
info.YarnCode.Add(yarn1); info.YarnCode.Add(yarn1);
if (!string.IsNullOrEmpty(yarn2)) if (!string.IsNullOrEmpty(yarn2))
@ -319,7 +322,7 @@ public class HyosungPlcService(ILogger<HyosungPlcService> logger) : IHyosungPlcS
private async Task QueryGetPrintLabel() private async Task QueryGetPrintLabel()
{ {
var trayCode = await _reader.ReadStringAsync(13000); var trayCode = await _reader.ReadStringAsync(13000);
if (!string.IsNullOrEmpty(trayCode)||!trayCode.StartsWith("0000")) if (!string.IsNullOrEmpty(trayCode)&&!trayCode.StartsWith("0000"))
{ {
await _reader.WriteStringAsync(13000, "00000000000000000000"); await _reader.WriteStringAsync(13000, "00000000000000000000");
OnRequestGetPrintLableOption?.Invoke(trayCode); OnRequestGetPrintLableOption?.Invoke(trayCode);
@ -344,4 +347,6 @@ public class HyosungPlcService(ILogger<HyosungPlcService> logger) : IHyosungPlcS
OnRequestPrintLabel?.Invoke(2, requestPrintLabel[2]); OnRequestPrintLabel?.Invoke(2, requestPrintLabel[2]);
} }
} }
} }

View File

@ -58,7 +58,9 @@ public interface IHyosungPlcService
Task WritePackLineOptionAsync(PackLineOption option); Task WritePackLineOptionAsync(PackLineOption option);
Task WritePrintLabelResultAsync(int index, int side, bool result); Task WritePrintLableOptionsAsync(int side);
Task WritePrintLabelResultAsync(int index, bool result);
/// <summary> /// <summary>
/// Plc请求扫描产品 /// Plc请求扫描产品

View File

@ -23,27 +23,71 @@ public class HikScanner(string host, int port)
_socket.Dispose(); _socket.Dispose();
} }
public async Task<string> ScanAsync() public async Task Restart()
{ {
try try
{ {
byte[] cmd = "start"u8.ToArray(); _socket.Close();
await _socket.SendAsync(cmd); }
byte[] buffer = new byte[1024]; finally
int len = await _socket.ReceiveAsync(buffer).WaitAsync(TimeSpan.FromMilliseconds(2000)); {
cmd = "stop"u8.ToArray();
await _socket.SendAsync(cmd); _socket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
await _socket.ConnectAsync(Host, Port);
}
}
public async Task Stop()
{
var cmd = "stop"u8.ToArray();
await _socket.SendAsync(cmd);
}
public async Task<string> ScanAsync()
{
var barcode = string.Empty;
try
{
if (!_socket.Connected)
{
_socket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
await _socket.ConnectAsync(Host, Port);
}
byte[] _ = new byte[1024]; byte[] _ = new byte[1024];
while (_socket.Available > 0) while (_socket.Available > 0)
{ {
await _socket.ReceiveAsync(_, SocketFlags.None); await _socket.ReceiveAsync(_, SocketFlags.None);
} }
return Encoding.ASCII.GetString(buffer, 0, len); _socket.ReceiveTimeout = 1000;
byte[] cmd = "start"u8.ToArray();
await _socket.SendAsync(cmd);
byte[] buffer = new byte[1024];
int len = await _socket.ReceiveAsync(buffer).WaitAsync(TimeSpan.FromMilliseconds(1000));
barcode= Encoding.ASCII.GetString(buffer, 0, len);
} }
catch (Exception e) catch (Exception e)
{ {
return string.Empty; _socket.Close();
_socket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
await _socket.ConnectAsync(Host, Port);
byte[] _ = new byte[1024];
while (_socket.Available > 0)
{
await _socket.ReceiveAsync(_, SocketFlags.None);
}
_socket.ReceiveTimeout = 1000;
byte[] cmd = "start"u8.ToArray();
await _socket.SendAsync(cmd);
byte[] buffer = new byte[1024];
int len = await _socket.ReceiveAsync(buffer).WaitAsync(TimeSpan.FromMilliseconds(1000));
barcode= Encoding.ASCII.GetString(buffer, 0, len);
} }
finally
{
var cmd = "stop"u8.ToArray();
await _socket.SendAsync(cmd);
}
return barcode;
// 清空缓冲区 防止收到之前的数据 // 清空缓冲区 防止收到之前的数据
} }
} }

View File

@ -102,42 +102,48 @@ public class HyosungScannerService : IHyosungScannerService
public async Task<Yarn?> ScanYarnAsync(int varietyId) public async Task<Yarn?> ScanYarnAsync(int varietyId)
{ {
List<Task<Yarn?>> ls = _yarnScanners.Select(scanner => scanner.ScanAsync() List<Task<string>> ls = _yarnScanners.Select(scanner => scanner.ScanAsync()).ToList();
.ContinueWith(task =>
{
if (task.IsCompletedSuccessfully && !string.IsNullOrEmpty(task.Result))
{
_logger.LogInformation($"scanner[{scanner.Host}:{scanner.Port}] scan yarn {task.Result}");
return Yarn.Create(task.Result, varietyId);
}
return null;
}))
.ToList();
//停止所有的扫码枪
while (ls.Count > 0) while (ls.Count > 0)
{ {
// 使用 Task.WhenAny 方法等待任意一个任务完成 // 使用 Task.WhenAny 方法等待任意一个任务完成
Task<Yarn?> completedTask = await Task.WhenAny(ls); Task<string> completedTask = await Task.WhenAny(ls);
// 移除已经完成的任务 // 移除已经完成的任务
ls.Remove(completedTask); ls.Remove(completedTask);
// 获取完成任务的结果 // 获取完成任务的结果
Yarn? result = await completedTask; string result = await completedTask;
// 如果结果不为空,立即返回结果 // 如果结果不为空,立即返回结果
if (result != null) if (!string.IsNullOrEmpty(result))
{ {
return result; _yarnScanners.Select(async scanner => await scanner.Stop());
return Yarn.Create(result, varietyId);
} }
} }
//_yarnScanners.Select( scanner => scanner.Stop());
_logger.LogWarning($"all scanner no scan yarn"); _logger.LogWarning($"all scanner no scan yarn");
_yarnScanners.Select(async scanner => await scanner.Restart());
// 如果所有任务都完成且没有找到非空结果,返回 null // 如果所有任务都完成且没有找到非空结果,返回 null
return null; return null;
} }
public async Task<string> ScanFixtureAsync(int fixtureId) public async Task<string> ScanFixtureAsync(int fixtureId)
{ {
return await _fixtureScanners[fixtureId].ScanAsync(); try
{
return await _fixtureScanners[fixtureId].ScanAsync();
}
catch(Exception e)
{
_logger.LogError(e, $"Fixture{fixtureId} Scan Error");
await _fixtureScanners[fixtureId].Restart();
return await _fixtureScanners[fixtureId].ScanAsync();
}
//string code = ""; //string code = "";
//do //do
//{ //{

View File

@ -32,5 +32,8 @@ public class AgvBinEntity
[SugarColumn(ColumnDescription = "排序")] [SugarColumn(ColumnDescription = "排序")]
public int Sort { get; set; } public int Sort { get; set; }
[SugarColumn(IsNullable =true)]
public string HeightCode { get; set; }
public bool IsDeleted { get; set; } public bool IsDeleted { get; set; }
} }

View File

@ -42,4 +42,6 @@ public class TrayEntity
[SugarColumn(IsNullable = true)] public int? AgvBinId { get; set; } [SugarColumn(IsNullable = true)] public int? AgvBinId { get; set; }
[SugarColumn(IsNullable = true)] public string? Barcode { get; set; } [SugarColumn(IsNullable = true)] public string? Barcode { get; set; }
[SugarColumn(IsNullable = true)] public bool? IsPacking { get; set; } = false;
} }

View File

@ -83,5 +83,8 @@ public class VarietyEntity
[SugarColumn(ColumnDescription = "副标签数量")] [SugarColumn(ColumnDescription = "副标签数量")]
public int SubLabelCount { get; set; } public int SubLabelCount { get; set; }
[SugarColumn(IsNullable =true)]
public int? LastNo { get; set; }
} }

View File

@ -38,6 +38,8 @@ public class Tray
public string? Barcode { get; set; } public string? Barcode { get; set; }
public bool? IsPacking { get; set; }
public TrayEntity ToEntity() public TrayEntity ToEntity()
{ {
return new TrayEntity() return new TrayEntity()
@ -58,7 +60,8 @@ public class Tray
Type = Type, Type = Type,
Unit = Unit, Unit = Unit,
AgvBinId = AgvBinId, AgvBinId = AgvBinId,
Barcode = Barcode Barcode = Barcode,
IsPacking= IsPacking
}; };
} }
@ -82,7 +85,8 @@ public class Tray
Type = entity.Type, Type = entity.Type,
Unit = entity.Unit, Unit = entity.Unit,
AgvBinId = entity.AgvBinId, AgvBinId = entity.AgvBinId,
Barcode = entity.Barcode Barcode = entity.Barcode,
IsPacking=entity.IsPacking
}; };
} }
} }

View File

@ -64,6 +64,8 @@ public class Variety
public bool IsTurn { get; set; } public bool IsTurn { get; set; }
public int? LastNo { get; set; }
public static Variety Create(VarietyEntity entity, List<PalletEntity> pallets) public static Variety Create(VarietyEntity entity, List<PalletEntity> pallets)
{ {
var variety = new Variety() var variety = new Variety()
@ -92,7 +94,8 @@ public class Variety
MiddlePallet = Pallet.FromEntity(pallets.First(x => x.Id == entity.MiddlePalletId)), MiddlePallet = Pallet.FromEntity(pallets.First(x => x.Id == entity.MiddlePalletId)),
TopAndBottomPallet = Pallet.FromEntity(pallets.First(x => x.Id == entity.TopAndBottomPalletId)), TopAndBottomPallet = Pallet.FromEntity(pallets.First(x => x.Id == entity.TopAndBottomPalletId)),
Tray = Pallet.FromEntity(pallets.First(x => x.Id == entity.TrayId)), Tray = Pallet.FromEntity(pallets.First(x => x.Id == entity.TrayId)),
HasBox = entity.HasBox HasBox = entity.HasBox,
LastNo = entity.LastNo
}; };
if (entity.PaperTrayId != null && entity.PaperTrayId != 0) if (entity.PaperTrayId != null && entity.PaperTrayId != 0)
variety.PaperTray = Pallet.FromEntity(pallets.First(x => x.Id == entity.PaperTrayId)); variety.PaperTray = Pallet.FromEntity(pallets.First(x => x.Id == entity.PaperTrayId));
@ -130,6 +133,7 @@ public class Variety
TopAndBottomPalletId = TopAndBottomPallet.Id, TopAndBottomPalletId = TopAndBottomPallet.Id,
TrayId = Tray.Id, TrayId = Tray.Id,
HasBox = HasBox, HasBox = HasBox,
LastNo=LastNo
}; };
return entity; return entity;
} }

View File

@ -19,18 +19,18 @@ public class AgvBinService : IAgvBinService
public async Task<AgvBinEntity> GetAvailableBin(int height) public async Task<AgvBinEntity> GetAvailableBin(int height)
{ {
var bin = await _repository.AsQueryable() var bin = await _repository.CopyNew().AsQueryable()
.Where(x => x.IsFree && !x.IsDeleted).OrderBy(x => x.Sort).FirstAsync(); .Where(x => x.IsFree && !x.IsDeleted).OrderBy(x => x.Sort).FirstAsync();
if (bin.BinCode == "B10") if (bin.BinCode == "B10")
{ {
await _repository.AsUpdateable() await _repository.CopyNew().AsUpdateable()
.Where(x => x.RackType == 2 && !x.IsDeleted) .Where(x => x.RackType == 2 && !x.IsDeleted)
.SetColumns(x => x.IsFree, true) .SetColumns(x => x.IsFree, true)
.ExecuteCommandAsync(); .ExecuteCommandAsync();
} }
else if (bin.BinCode == "B33") else if (bin.BinCode == "B33")
{ {
await _repository.AsUpdateable() await _repository.CopyNew().AsUpdateable()
.Where(x => x.RackType == 1 && !x.IsDeleted) .Where(x => x.RackType == 1 && !x.IsDeleted)
.SetColumns(x => x.IsFree, true) .SetColumns(x => x.IsFree, true)
.ExecuteCommandAsync(); .ExecuteCommandAsync();
@ -43,6 +43,6 @@ public class AgvBinService : IAgvBinService
{ {
entity.IsFree = false; entity.IsFree = false;
_cache.First(e => e.Id == entity.Id).IsFree = false; _cache.First(e => e.Id == entity.Id).IsFree = false;
return _repository.UpdateAsync(entity); return _repository.CopyNew().UpdateAsync(entity);
} }
} }

View File

@ -22,11 +22,23 @@ public class DictService : IDictService
public async Task<string> GetKeyAsync(string type, string name) public async Task<string> GetKeyAsync(string type, string name)
{ {
return _cache.FirstOrDefault(d => d.Type == type && d.Value == name)?.Value ?? ""; return _cache.FirstOrDefault(d => d.Type == type && d.Value == name)?.Key ?? "";
} }
public async Task<List<DictEntity>> GetDictsByTypeAsync(string type) public async Task<List<DictEntity>> GetDictsByTypeAsync(string type)
{ {
return _cache.Where(d => d.Type == type).ToList(); return _cache.Where(d => d.Type == type).ToList();
} }
public async Task SetValue(string type, string key, string value)
{
await _repository.CopyNew().AsUpdateable()
.Where(x => x.Type == type && x.Key == key).SetColumns(x => x.Value, value).ExecuteCommandAsync(); ;
}
public async Task<string> GetValue(string type, string key)
{
var dict = await _repository.CopyNew().GetFirstAsync(x => x.Type == type && x.Key == key);
return dict.Value;
}
} }

View File

@ -7,4 +7,8 @@ public interface IDictService
Task<string> GetKeyAsync(string type, string value); Task<string> GetKeyAsync(string type, string value);
Task<List<DictEntity>> GetDictsByTypeAsync(string type); Task<List<DictEntity>> GetDictsByTypeAsync(string type);
Task SetValue(string type, string key,string value);
Task<string> GetValue(string type, string key);
} }

View File

@ -27,6 +27,8 @@ public interface ITrayService
/// <returns></returns> /// <returns></returns>
Task<Tray> GetByCode(string code); Task<Tray> GetByCode(string code);
Task<Tray> GetIsPacking();
/// <summary> /// <summary>
/// 生成控制号 /// 生成控制号
/// </summary> /// </summary>

View File

@ -39,4 +39,9 @@ public interface IVarietyService
/// <param name="pallet"></param> /// <param name="pallet"></param>
/// <returns></returns> /// <returns></returns>
Task AddPalletAsync(Pallet pallet); Task AddPalletAsync(Pallet pallet);
Task SetLastNo(int varietyId, int lastNo);
Task<int?> GetLastNo(int varietyId);
} }

View File

@ -6,25 +6,29 @@ using Seyounth.Hyosung.Data.Models;
using Seyounth.Hyosung.Data.Repositories; using Seyounth.Hyosung.Data.Repositories;
using Seyounth.Hyosung.Data.Services.Hyosung; using Seyounth.Hyosung.Data.Services.Hyosung;
using Seyounth.Hyosung.Data.Services.Hyosung.Entities; using Seyounth.Hyosung.Data.Services.Hyosung.Entities;
using SqlSugar;
namespace Seyounth.Hyosung.Data.Services; namespace Seyounth.Hyosung.Data.Services;
public class TrayService : ITrayService public class TrayService : ITrayService
{ {
private readonly ConcurrentDictionary<string, Tray> _cache = new(); //private readonly ConcurrentDictionary<string, Tray> _cache = new();
private readonly IRepository<TrayEntity> _repository; // private readonly <TrayEntity> _repository;
private readonly IHyosungWmsService _hyosungWmsService; private readonly IHyosungWmsService _hyosungWmsService;
public TrayService(IServiceProvider provider, IHyosungWmsService hyosungWmsService) private readonly ISqlSugarClient _db;
public TrayService(IServiceProvider provider, IHyosungWmsService hyosungWmsService,ISqlSugarClient db)
{ {
_repository = provider.CreateScope().ServiceProvider.GetRequiredService<IRepository<TrayEntity>>(); _db = db;
// _repository = provider.CreateScope().ServiceProvider.GetRequiredService<IRepository<TrayEntity>>();
//_repository = provider.GetService<IRepository<TrayEntity>>(); //_repository = provider.GetService<IRepository<TrayEntity>>();
var trays = _repository.GetList(t => t.ControlNo == null); // var trays = _db.Queryable<TrayEntity>().Where(t => t.ControlNo == null).ToListAsync().Result;
_hyosungWmsService = hyosungWmsService; _hyosungWmsService = hyosungWmsService;
foreach (var tray in trays) //foreach (var tray in trays)
{ //{
_cache.TryAdd(tray.TrayCode, Tray.FromEntity(tray)); // _cache.TryAdd(tray.TrayCode, Tray.FromEntity(tray));
} //}
} }
public async Task<Tray> GeneraNewTray(int varietyId) public async Task<Tray> GeneraNewTray(int varietyId)
@ -35,29 +39,29 @@ public class TrayService : ITrayService
VarietyId = varietyId, VarietyId = varietyId,
CreateTime = DateTime.Now CreateTime = DateTime.Now
}; };
var count = await _repository.CountAsync(t => t.VarietyId == tray.VarietyId); var count = await _db.CopyNew().Queryable<TrayEntity>().CountAsync(t => t.VarietyId == tray.VarietyId);
tray.IsEven = count % 2 == 0; tray.IsEven = count % 2 == 0;
var identity = await _repository.InsertReturnIdentityAsync(tray.ToEntity()); var identity = await _db.CopyNew().Insertable<TrayEntity>(tray.ToEntity()).ExecuteReturnIdentityAsync();
tray.Id = identity; tray.Id = identity;
_cache.TryAdd(tray.TrayCode, tray); // _cache.TryAdd(tray.TrayCode, tray);
return tray; return tray;
} }
public async Task<int> GetIdByCode(string code) public async Task<int> GetIdByCode(string code)
{ {
try //try
{ //{
return _cache[code].Id; // return _cache[code].Id;
} //}
catch //catch
{ //{
return (await _repository.GetFirstAsync(d => d.TrayCode == code)).Id; return (await _db.CopyNew().Queryable<TrayEntity>().Where(d => d.TrayCode == code).FirstAsync()).Id;
} // }
} }
public async Task<Tray> GetByCode(string code) public async Task<Tray> GetByCode(string code)
{ {
return Tray.FromEntity(await _repository.GetSingleAsync(t => t.TrayCode == code)); return Tray.FromEntity(await _db.CopyNew().Queryable<TrayEntity>().Where(t => t.TrayCode == code).FirstAsync());
} }
public Task StorageAsync(string trayCode, int stackHeight, int controlNo, MST_ITEM_2240_V itemInfo) public Task StorageAsync(string trayCode, int stackHeight, int controlNo, MST_ITEM_2240_V itemInfo)
@ -68,14 +72,14 @@ public class TrayService : ITrayService
public async Task<Tray> PrintTrayAsync(string trayCode, int controlNo, MST_ITEM_2240_V itemInfo) public async Task<Tray> PrintTrayAsync(string trayCode, int controlNo, MST_ITEM_2240_V itemInfo)
{ {
Tray tray; Tray tray;
try //try
{ //{
tray = _cache[trayCode]; // tray = _cache[trayCode];
} //}
catch //catch
{ //{
tray = await GetByCode(trayCode); tray = await GetByCode(trayCode);
} //}
tray.ControlNo = controlNo; tray.ControlNo = controlNo;
tray.Grade = itemInfo.GRADE; tray.Grade = itemInfo.GRADE;
@ -87,23 +91,32 @@ public class TrayService : ITrayService
tray.GrossWeight = itemInfo.GROSS_WEIGHT; tray.GrossWeight = itemInfo.GROSS_WEIGHT;
tray.Barcode = tray.Barcode =
$"{itemInfo.ITEM_CODE} {DateTime.Now:yyMMdd}00{itemInfo.LOTNO.PadLeft(4, '0')}{controlNo.ToString().PadLeft(4, '0')}0"; $"{itemInfo.ITEM_CODE} {DateTime.Now:yyMMdd}00{itemInfo.LOTNO.PadLeft(4, '0')}{controlNo.ToString().PadLeft(4, '0')}0";
await _repository.UpdateAsync(tray.ToEntity()); await _db.Updateable<TrayEntity>(tray.ToEntity()).ExecuteCommandAsync();
_cache.Remove(tray.TrayCode, out _); // _cache.Remove(tray.TrayCode, out _);
return tray; return tray;
} }
public async Task StorageAsync(string trayCode) public async Task StorageAsync(string trayCode)
{ {
var tray = await _repository.GetFirstAsync(d => d.TrayCode == trayCode); var tray = await _db.CopyNew().Queryable<TrayEntity>().Where(d => d.TrayCode == trayCode).FirstAsync();
tray.FinishTime = DateTime.Now; tray.FinishTime = DateTime.Now;
await _repository.UpdateAsync(tray); tray.IsPacking = true;
_cache.TryRemove(tray.TrayCode, out _); await _db.CopyNew().Updateable<TrayEntity>(tray).ExecuteCommandAsync();
// _cache.TryRemove(tray.TrayCode, out _);
} }
public async Task UpdateHeightAsync(string trayCode, int height) public async Task UpdateHeightAsync(string trayCode, int height)
{ {
await _repository.AsUpdateable() await _db.CopyNew().Updateable<TrayEntity>()
.Where(x => x.TrayCode == trayCode) .Where(x => x.TrayCode == trayCode)
.SetColumns(x => x.StackHeight, height).ExecuteCommandAsync(); .SetColumns(x => x.StackHeight, height)
.SetColumns(x => x.IsPacking, false)
.ExecuteCommandAsync();
}
public async Task<Tray> GetIsPacking()
{
var tray= await _db.CopyNew().Queryable<TrayEntity>().Where(x => x.IsPacking!=null&&x.IsPacking.Value).FirstAsync();
return Tray.FromEntity(tray);
} }
} }

View File

@ -86,4 +86,18 @@ public class VarietyService : IVarietyService
{ {
return _varietiesCache.Select(v => Variety.Create(v, _palletsCache.ToList())).ToList(); return _varietiesCache.Select(v => Variety.Create(v, _palletsCache.ToList())).ToList();
} }
public async Task<int?> GetLastNo(int varietyId)
{
var variety = await (_varietyRepository.CopyNew().GetFirstAsync(x=>x.Id==varietyId));
return variety.LastNo;
}
public async Task SetLastNo(int varietyId,int lastNo)
{
await _varietyRepository.CopyNew().AsUpdateable()
.Where(x => x.Id == varietyId)
.SetColumns(x => x.LastNo , lastNo)
.ExecuteCommandAsync();
}
} }

View File

@ -26,7 +26,7 @@ public class YarnService : IYarnService
public async Task<Yarn?> AddYarnAsync(Yarn yarn) public async Task<Yarn?> AddYarnAsync(Yarn yarn)
{ {
var id = await _yarnRepository.InsertReturnIdentityAsync(yarn.ToEntity()); var id = await _yarnRepository.CopyNew().InsertReturnIdentityAsync(yarn.ToEntity());
yarn.Id = id; yarn.Id = id;
NoFinished.TryAdd(yarn.ScanCode, yarn); NoFinished.TryAdd(yarn.ScanCode, yarn);
return yarn; return yarn;
@ -34,7 +34,7 @@ public class YarnService : IYarnService
public async Task<List<Yarn>> GetYarnsByTrayIdAsync(int trayId) public async Task<List<Yarn>> GetYarnsByTrayIdAsync(int trayId)
{ {
return (await _yarnRepository.GetListAsync(y => y.TrayId == trayId)) return (await _yarnRepository.CopyNew().GetListAsync(y => y.TrayId == trayId))
.Select(Yarn.FromEntity).ToList(); .Select(Yarn.FromEntity).ToList();
} }
@ -46,7 +46,7 @@ public class YarnService : IYarnService
} }
catch catch
{ {
return Yarn.FromEntity(await _yarnRepository.GetFirstAsync(d => d.ScanCode == code)) ; return Yarn.FromEntity(await _yarnRepository.CopyNew().GetFirstAsync(d => d.ScanCode == code)) ;
} }
} }
@ -55,7 +55,7 @@ public class YarnService : IYarnService
{ {
var yarn = NoFinished[yarnCode]; var yarn = NoFinished[yarnCode];
yarn.IsFinished = true; yarn.IsFinished = true;
await _yarnRepository.UpdateAsync(yarn.ToEntity()); await _yarnRepository.CopyNew().UpdateAsync(yarn.ToEntity());
NoFinished.TryRemove(yarnCode, out _); NoFinished.TryRemove(yarnCode, out _);
} }
@ -66,7 +66,7 @@ public class YarnService : IYarnService
yarn.StackTime = DateTime.Now; yarn.StackTime = DateTime.Now;
yarn.IsFinished = true; yarn.IsFinished = true;
yarn.IsFinished = true; yarn.IsFinished = true;
await _yarnRepository.UpdateAsync(yarn.ToEntity()); await _yarnRepository.CopyNew().UpdateAsync(yarn.ToEntity());
NoFinished.TryRemove(yarnCode, out _); NoFinished.TryRemove(yarnCode, out _);
} }
} }

View File

@ -25,12 +25,15 @@ public class HyosungRuntime(
ITrayService trayService, ITrayService trayService,
IVarietyService varietyService, IVarietyService varietyService,
IHyosungAgvService hyosungAgvService, IHyosungAgvService hyosungAgvService,
IHyosungWmsService hyosungWmsService) : IHyosungRuntime IHyosungWmsService hyosungWmsService,
IDictService dictService) : IHyosungRuntime
{ {
public PackLineOption PackLineOption { get; private set; } public PackLineOption PackLineOption { get; private set; }
public StackStationModel Stack1 { get; private set; } = new(); public StackStationModel Stack1 { get; private set; } = new();
public StackStationModel Stack2 { get; private set; } = new(); public StackStationModel Stack2 { get; private set; } = new();
private ConcurrentQueue<int> _packingQueue = new ConcurrentQueue<int>();
private string currentPrintTrayCode = ""; private string currentPrintTrayCode = "";
public async Task StartAsync(CancellationToken token) public async Task StartAsync(CancellationToken token)
@ -153,6 +156,7 @@ public class HyosungRuntime(
{ {
await trayService.StorageAsync(info.TrayCode); await trayService.StorageAsync(info.TrayCode);
await hyosungAgvService.StorageAsync(info.TrayCode); await hyosungAgvService.StorageAsync(info.TrayCode);
_packingQueue?.TryDequeue(out _);
//标志下线已完成 //标志下线已完成
await hyosungPlcService.LeaveCompletedAsync(); await hyosungPlcService.LeaveCompletedAsync();
logger.LogInformation($"plc leaving production line success"); logger.LogInformation($"plc leaving production line success");
@ -257,26 +261,44 @@ public class HyosungRuntime(
logger.LogInformation($"plc request pack line option"); logger.LogInformation($"plc request pack line option");
try try
{ {
var tray = await trayService.GetByCode(arg); var tray = await trayService.GetByCode(arg);
var variety = await varietyService.GetById(tray.VarietyId); var variety = await varietyService.GetById(tray.VarietyId);
if (_packingQueue is null)
_packingQueue = new ConcurrentQueue<int>();
_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+count;
var isEven = control % 2 == 0;
PackLineOption = new PackLineOption() PackLineOption = new PackLineOption()
{ {
HeadCount = variety.StackHeadCount ?? 0, HeadCount = variety.StackHeadCount ?? 0,
HasBox = variety.HasBox, HasBox = variety.HasBox,
IsTop = variety.NeedTopBoard is NeedType.Need or NeedType.NotNeed
? variety.NeedTopBoard == NeedType.Need
: tray.IsEven && variety.NeedTopBoard == NeedType.EvenNeed,
IsPack = variety.NeedPackStrap is NeedType.Need or NeedType.NotNeed
? variety.NeedPackStrap == NeedType.Need
: tray.IsEven && variety.NeedPackStrap == NeedType.EvenNeed,
IsFilm = variety.NeedFilmWrapping is NeedType.Need or NeedType.NotNeed
? variety.NeedFilmWrapping == NeedType.Need
: tray.IsEven && variety.NeedFilmWrapping == NeedType.EvenNeed,
IsLam = variety.NeedFilmCoating is NeedType.Need or NeedType.NotNeed
? variety.NeedFilmCoating == NeedType.Need
: tray.IsEven && variety.NeedFilmCoating == NeedType.EvenNeed,
TrayCode = arg 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); await hyosungPlcService.WritePackLineOptionAsync(PackLineOption);
logger.LogInformation($"plc request pack line option success"); logger.LogInformation($"plc request pack line option success");
} }
@ -294,12 +316,18 @@ public class HyosungRuntime(
var mod = await hyosungWmsService.GetItemInfoByItemCode(variety.Code); var mod = await hyosungWmsService.GetItemInfoByItemCode(variety.Code);
var grade = "1"; var grade = "1";
if (mod.GRADE != "AA") grade = mod.GRADE; if (mod.GRADE != "AA") grade = mod.GRADE;
int controlNo = 0; int? controlNo;
if (tray.ControlNo is null || tray.ControlNo == 0) if (tray.ControlNo is null || tray.ControlNo == 0)
{ {
controlNo = await hyosungWmsService.GetControlNo(variety, grade); controlNo = await varietyService.GetLastNo(variety.Id);
tray = await trayService.PrintTrayAsync(arg, controlNo, mod); if (controlNo is null)
controlNo = await hyosungWmsService.GetControlNo(variety, grade);
else
controlNo += 1;
tray = await trayService.PrintTrayAsync(arg, controlNo.Value, mod);
} }
await dictService.SetValue("System", "CurrentPackingTrayCode", arg);
await hyosungPlcService.WritePrintLableOptionsAsync( variety.MasterLabelCount);
} }
/// <summary> /// <summary>
@ -311,23 +339,26 @@ public class HyosungRuntime(
/// <exception cref="NotImplementedException"></exception> /// <exception cref="NotImplementedException"></exception>
private async Task OnPlcRequestPrintLabel(int arg1, int height) private async Task OnPlcRequestPrintLabel(int arg1, int height)
{ {
logger.LogInformation($"plc request print label:{arg1} {currentPrintTrayCode} {height}"); var trayCode = await dictService.GetValue("System", "CurrentPackingTrayCode");
var tray = await trayService.GetByCode(currentPrintTrayCode); 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); var variety = await varietyService.GetById(tray.VarietyId);
await trayService.UpdateHeightAsync(currentPrintTrayCode, height); await trayService.UpdateHeightAsync(tray.TrayCode, height);
try try
{ {
if (arg1 == 1) if (arg1 == 1)
{ {
await printer.PrintAsync(1, currentPrintTrayCode); await printer.PrintAsync(1, tray.TrayCode);
await hyosungPlcService.WritePrintLabelResultAsync(arg1, variety.SubLabelCount, true); await hyosungPlcService.WritePrintLabelResultAsync(arg1, true);
} }
else else
{ {
await printer.PrintAsync(2, currentPrintTrayCode); await printer.PrintAsync(2, tray.TrayCode);
await hyosungPlcService.WritePrintLabelResultAsync(arg1, variety.MasterLabelCount, true); await hyosungPlcService.WritePrintLabelResultAsync(arg1, true);
await hyosungWmsService.UpdateControlNo(variety, tray.ControlNo.Value); await varietyService.SetLastNo(variety.Id, tray.ControlNo.Value);
//await hyosungWmsService.UpdateControlNo(variety, tray.ControlNo.Value);
await hyosungWmsService.AddLabelResult(new LabelResult(tray, variety)); await hyosungWmsService.AddLabelResult(new LabelResult(tray, variety));
} }
@ -337,7 +368,7 @@ public class HyosungRuntime(
} }
catch (Exception e) catch (Exception e)
{ {
await hyosungPlcService.WritePrintLabelResultAsync(arg1, 1, false); await hyosungPlcService.WritePrintLabelResultAsync(arg1, false);
logger.LogError(e, "print label fail"); logger.LogError(e, "print label fail");
} }
} }

View File

@ -19,6 +19,8 @@ public partial class HomeViewModel : ObservableObject
[ObservableProperty] private List<string> _yarnCarTypes; [ObservableProperty] private List<string> _yarnCarTypes;
[ObservableProperty] private List<string> _yarnCarSide;
[ObservableProperty] private Variety _selectedVariety; [ObservableProperty] private Variety _selectedVariety;
[ObservableProperty] private PackLineOption _packLineOption; [ObservableProperty] private PackLineOption _packLineOption;
@ -36,6 +38,9 @@ public partial class HomeViewModel : ObservableObject
_yarnCarTypes.Add("B"); _yarnCarTypes.Add("B");
_yarnCarTypes.Add("C"); _yarnCarTypes.Add("C");
_yarnCarTypes.Add("D"); _yarnCarTypes.Add("D");
_yarnCarSide = new();
_yarnCarSide.Add("正面");
_yarnCarSide.Add("反面");
_varieties = new ObservableCollection<Variety>(varietyService.GetAll()); _varieties = new ObservableCollection<Variety>(varietyService.GetAll());
DispatcherTimer timer = new DispatcherTimer(); DispatcherTimer timer = new DispatcherTimer();
timer = new DispatcherTimer(); timer = new DispatcherTimer();

View File

@ -173,11 +173,12 @@
Foreground="White" Foreground="White"
ItemsSource="{Binding ViewModel.YarnCarTypes}" /> ItemsSource="{Binding ViewModel.YarnCarTypes}" />
<TextBlock VerticalAlignment="Center" Margin="10" <TextBlock VerticalAlignment="Center" Margin="10"
Foreground="White" Grid.Row="2" Grid.Column="0" Text="码垛层数:" /> Foreground="White" Grid.Row="2" Grid.Column="0" Text="纱车正反面:" />
<TextBox Grid.Column="1" Margin="10" Grid.Row="2" IsEnabled="False" <ComboBox x:Name="YarnSideComboBox" Grid.Column="1" Margin="10" Grid.Row="2"
TextAlignment="Right" HorizontalAlignment="Stretch"
Foreground="White" HorizontalContentAlignment="Right"
Text="{Binding ViewModel.SelectedVariety.StackingLayers}" /> Foreground="White"
ItemsSource="{Binding ViewModel.YarnCarSide}" />
<TextBlock VerticalAlignment="Center" Margin="10" <TextBlock VerticalAlignment="Center" Margin="10"
Foreground="White" Grid.Row="3" Grid.Column="0" Text="总数:" /> Foreground="White" Grid.Row="3" Grid.Column="0" Text="总数:" />
<TextBox Grid.Column="1" Margin="10" Grid.Row="3" IsEnabled="False" <TextBox Grid.Column="1" Margin="10" Grid.Row="3" IsEnabled="False"

View File

@ -2,6 +2,7 @@
using System.Windows.Controls; using System.Windows.Controls;
using MaterialDesignThemes.Wpf; using MaterialDesignThemes.Wpf;
using Seyounth.Hyosung.Data.Models; using Seyounth.Hyosung.Data.Models;
using Seyounth.Hyosung.Data.Services;
using Seyounth.Hyosung.Data.Services.Hyosung; using Seyounth.Hyosung.Data.Services.Hyosung;
using Seyounth.Hyosung.Runtime; using Seyounth.Hyosung.Runtime;
using Seyounth.Hyosung.ViewModels; using Seyounth.Hyosung.ViewModels;
@ -19,7 +20,10 @@ namespace Seyounth.Hyosung.Views.Pages
private readonly IHyosungWmsService _wmsService; private readonly IHyosungWmsService _wmsService;
public HomeViewPage(HomeViewModel viewModel, IHyosungRuntime runtime, IHyosungWmsService wmsService) public HomeViewPage(HomeViewModel viewModel,
IHyosungRuntime runtime,
IHyosungWmsService wmsService,
IVarietyService varietyService)
{ {
_wmsService = wmsService; _wmsService = wmsService;
_runtime = runtime; _runtime = runtime;
@ -41,7 +45,7 @@ namespace Seyounth.Hyosung.Views.Pages
ButtonProgressAssist.SetIsIndicatorVisible(ChangeVarietyButton, true); ButtonProgressAssist.SetIsIndicatorVisible(ChangeVarietyButton, true);
ChangeVarietyButton.IsEnabled = false; ChangeVarietyButton.IsEnabled = false;
variety.YarnCarSide = 1; variety.YarnCarSide = YarnSideComboBox.SelectedIndex+1;
variety.YarnCarType = YarnCarTypeComboBox.SelectedIndex + 1; variety.YarnCarType = YarnCarTypeComboBox.SelectedIndex + 1;
_runtime.SendVarietyToPlcAsync(variety) _runtime.SendVarietyToPlcAsync(variety)
.ContinueWith(task => .ContinueWith(task =>
@ -67,7 +71,11 @@ namespace Seyounth.Hyosung.Views.Pages
{ {
var variety = selectedItem as Variety; var variety = selectedItem as Variety;
var info = await _wmsService.GetItemInfoByItemCode(variety.Code); var info = await _wmsService.GetItemInfoByItemCode(variety.Code);
var controlNo = await _wmsService.GetControlNo(variety, info.GRADE); int? controlNo;
if (variety.LastNo is null || variety.LastNo == 0)
controlNo = await _wmsService.GetControlNo(variety, info.GRADE);
else
controlNo = variety.LastNo + 1;
await Dispatcher.InvokeAsync(() => await Dispatcher.InvokeAsync(() =>
{ {
ControlNoTextBlock.Text = $"控制号: {controlNo}"; ControlNoTextBlock.Text = $"控制号: {controlNo}";