|
|
using Admin.Core.Common.Helper;
|
|
|
using Admin.Core.IService;
|
|
|
using Admin.Core.Model;
|
|
|
using Admin.Core.Model.Model_New;
|
|
|
using Admin.Core.Service;
|
|
|
using Admin.Core.Socket;
|
|
|
using Aucma.Core.Palletiz.config;
|
|
|
using Aucma.Core.PLc;
|
|
|
using log4net;
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
using System.Text;
|
|
|
using System.Text.RegularExpressions;
|
|
|
using System.Threading.Tasks;
|
|
|
using TouchSocket.Sockets;
|
|
|
|
|
|
namespace Aucma.Core.Palletiz.Business
|
|
|
{
|
|
|
internal class InStoreBusiness
|
|
|
{
|
|
|
private static readonly log4net.ILog _logger = LogManager.GetLogger(typeof(InStoreBusiness));
|
|
|
|
|
|
private readonly IProductOffLineServices _offlineService;
|
|
|
|
|
|
private readonly IBaseSpaceInfoServices _spaceinfoService;
|
|
|
|
|
|
private readonly AppConfig _appConfig;
|
|
|
|
|
|
|
|
|
private const string BarcodeRef = "6933973114570;1621240AP0098E3D3497";
|
|
|
|
|
|
private readonly PlcModel plcCon = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("OldMelsecPlc1"));
|
|
|
|
|
|
public InStoreBusiness()
|
|
|
{
|
|
|
_appConfig = new AppConfig();
|
|
|
_spaceinfoService = App.ServiceProvider.GetService<IBaseSpaceInfoServices>();
|
|
|
_offlineService = App.ServiceProvider.GetService<IProductOffLineServices>();
|
|
|
|
|
|
}
|
|
|
|
|
|
public void Init()
|
|
|
{
|
|
|
TouchSocketService.ReceivedClientBufferEvent += ReceivedBuffer;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// Buffer缓冲
|
|
|
/// </summary>
|
|
|
/// <param name="buffer"></param>
|
|
|
private void ReceivedBuffer(SocketClient client, byte[] buffer)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
//_logger.LogInformation($"接收客户端:{client.Id};原始报文:{_stringChange.bytesToHexStr(buffer, buffer.Length)}");
|
|
|
do
|
|
|
{
|
|
|
string asciiStr = Encoding.ASCII.GetString(buffer);
|
|
|
|
|
|
if (asciiStr.Contains("heartbeat"))
|
|
|
{
|
|
|
_logger.Info($"收到客户端:{client.Id};心跳指令:{asciiStr}");
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
if (asciiStr.Contains("NoRead"))
|
|
|
{
|
|
|
NoReadHandle(client.Id);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
_logger.Info($"收到客户端:{client.Id}条码信息:{asciiStr}");
|
|
|
InStore(client.Id, asciiStr);
|
|
|
} while (false);
|
|
|
}
|
|
|
catch (Exception e)
|
|
|
{
|
|
|
_logger.Error($"Buffer缓冲异常:{e.Message}");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 入库申请
|
|
|
/// </summary>
|
|
|
/// <param name="spaceArea">货道区域</param>
|
|
|
/// <param name="asciiStr"></param>
|
|
|
private void InStore(string spaceArea, string asciiStr)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (string.IsNullOrEmpty(asciiStr))
|
|
|
{
|
|
|
throw new ArgumentException($"入库申请处理异常:条码信息为空");
|
|
|
}
|
|
|
|
|
|
if (string.IsNullOrEmpty(spaceArea))
|
|
|
{
|
|
|
throw new ArgumentException($"入库申请处理异常:货道区域为空");
|
|
|
}
|
|
|
|
|
|
if (asciiStr.Contains(";") && asciiStr.Length == BarcodeRef.Length)
|
|
|
{
|
|
|
string[] splitStr = asciiStr.Split(";");
|
|
|
if (splitStr.Length > 1)
|
|
|
{
|
|
|
asciiStr = splitStr[1];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
_offlineService.GetProductInfosBySnCode(asciiStr, out ProductOffline prodInfo);
|
|
|
|
|
|
if (prodInfo == null)
|
|
|
{
|
|
|
throw new ArgumentException($"入库申请处理异常:根据成品码获取成品信息为空");
|
|
|
}
|
|
|
|
|
|
GetSpaceInfoByMaterialType(spaceArea, prodInfo, out BaseSpaceInfo laseSpaceinfo,
|
|
|
out BaseSpaceInfo spaceinfo);
|
|
|
bool result = false;
|
|
|
SendInStoreTask(spaceinfo, ref result);
|
|
|
|
|
|
if (!result)
|
|
|
{
|
|
|
throw new ArgumentException($"入库申请处理异常:入库任务下发至PLC失败");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
List<BaseSpaceInfo> spaceinfos = new List<BaseSpaceInfo>();
|
|
|
if (laseSpaceinfo != null)
|
|
|
{
|
|
|
laseSpaceinfo.InStoreFlag = 1;
|
|
|
spaceinfos.Add(laseSpaceinfo);
|
|
|
}
|
|
|
|
|
|
spaceinfo.InStoreFlag = 3;
|
|
|
spaceinfos.Add(spaceinfo);
|
|
|
_spaceinfoService.UpdateSpaceInfo(spaceinfos);
|
|
|
}
|
|
|
}
|
|
|
catch (Exception e)
|
|
|
{
|
|
|
Console.WriteLine(e.Message);
|
|
|
//异常处理,手动入库
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 通过物料型号获取货道信息
|
|
|
/// </summary>
|
|
|
/// <param name="spaceArea"></param>
|
|
|
/// <param name="prodInfo"></param>
|
|
|
/// <param name="laseSpaceinfo"></param>
|
|
|
/// <param name="spaceinfo"></param>
|
|
|
/// <param name="isBig"></param>
|
|
|
/// <exception cref="ArgumentException"></exception>
|
|
|
private void GetSpaceInfoByMaterialType(string spaceArea, ProductOffline prodInfo, out BaseSpaceInfo laseSpaceinfo, out BaseSpaceInfo spaceinfo, bool isBig = false)
|
|
|
{
|
|
|
List<BaseSpaceInfo> spaceinfos = null;
|
|
|
if (isBig)
|
|
|
{
|
|
|
_spaceinfoService.GetSpaceInfosByExpression(out spaceinfos, x => x.StoreCode == _appConfig.storeCode && x.SpaceArea == spaceArea && x.MaterialType == prodInfo.ProductCode && x.SpaceType == 1);
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_spaceinfoService.GetSpaceInfosByExpression(out spaceinfos, x => x.StoreCode == _appConfig.storeCode && x.SpaceArea == spaceArea && x.MaterialType == prodInfo.ProductCode);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (spaceinfos == null)
|
|
|
{
|
|
|
throw new ArgumentException($"通过物料型号获取货道信息异常:根据成品信息获取货道信息为空");
|
|
|
}
|
|
|
|
|
|
spaceinfos = spaceinfos.OrderBy(x => x.ObjId).ToList();
|
|
|
|
|
|
MatchSpaceInfoByPlc(ref spaceinfos);
|
|
|
|
|
|
if (spaceinfos == null)
|
|
|
{
|
|
|
throw new ArgumentException($"通过物料型号获取货道信息异常:通过PLC匹配可用货道信息为空");
|
|
|
}
|
|
|
|
|
|
FiltrateSpaceInfo(spaceinfos, out laseSpaceinfo, out spaceinfo);
|
|
|
|
|
|
if (spaceinfo == null)
|
|
|
{
|
|
|
throw new ArgumentException($"通过物料型号获取货道信息异常:未获取到匹配的货道信息");
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 通过PLC匹配获取,去除已满的货道
|
|
|
/// </summary>
|
|
|
/// <param name="spaceinfos"></param>
|
|
|
private void MatchSpaceInfoByPlc(ref List<BaseSpaceInfo> spaceinfos)
|
|
|
{
|
|
|
|
|
|
if (plcCon == null)
|
|
|
{
|
|
|
throw new ArgumentException($"通过PLC匹配获取货道信息异常:Plc连接为空");
|
|
|
}
|
|
|
|
|
|
var _plc = plcCon.plc;
|
|
|
|
|
|
foreach (var item in spaceinfos)
|
|
|
{
|
|
|
item.SpaceCode = ExtractNumber(item.SpaceName);
|
|
|
var plcAddress = _appConfig.plcAddr.Where(x => x.spaceCode.ToString() == item.SpaceCode && x.spaceArea == item.SpaceArea).First();
|
|
|
int isFlag = _plc.ReadInt16(plcAddress.address);
|
|
|
if (isFlag == 1)
|
|
|
{
|
|
|
item.SpaceStatus = 3;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
spaceinfos = spaceinfos.Where(x => x.SpaceStatus != 3).ToList();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 筛选货道信息
|
|
|
/// </summary>
|
|
|
/// <param name="spaceinfos"></param>
|
|
|
/// <param name="spaceinfo"></param>
|
|
|
/// <exception cref="ArgumentException"></exception>
|
|
|
private void FiltrateSpaceInfo(List<BaseSpaceInfo> spaceinfos, out BaseSpaceInfo laseSpaceinfo, out BaseSpaceInfo spaceinfo)
|
|
|
{
|
|
|
if (spaceinfos == null)
|
|
|
{
|
|
|
throw new ArgumentException($"筛选货道信息异常:传入货道信息参数为空");
|
|
|
}
|
|
|
|
|
|
int count = spaceinfos.Where(x => x.InStoreFlag == 3).ToList().Count;
|
|
|
if (count > 0)
|
|
|
{
|
|
|
int index = spaceinfos.FindIndex(entity => entity.InStoreFlag == 3);
|
|
|
laseSpaceinfo = spaceinfos[index];
|
|
|
int nextIndex = (index + 1) % spaceinfos.Count;
|
|
|
spaceinfo = spaceinfos[nextIndex];
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
laseSpaceinfo = null;
|
|
|
spaceinfo = spaceinfos.First();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 下发入库任务至PLC
|
|
|
/// </summary>
|
|
|
/// <param name="spaceinfo"></param>
|
|
|
/// <param name="result"></param>
|
|
|
/// <exception cref="ArgumentException"></exception>
|
|
|
private void SendInStoreTask(BaseSpaceInfo spaceinfo, ref bool result)
|
|
|
{
|
|
|
if (plcCon == null)
|
|
|
{
|
|
|
throw new ArgumentException($"下发入库任务至PLC逻辑异常:Plc连接为空");
|
|
|
}
|
|
|
|
|
|
var _plc = plcCon.plc;
|
|
|
|
|
|
bool isFlag = true;
|
|
|
|
|
|
while (isFlag)
|
|
|
{
|
|
|
bool answerFlag = _plc.ReadBool("X1000");
|
|
|
|
|
|
if (answerFlag)
|
|
|
{
|
|
|
isFlag = false;
|
|
|
}
|
|
|
|
|
|
Task.Delay(1000 * 2).Wait();
|
|
|
}
|
|
|
|
|
|
int spaceCode = StringChange.ParseToInt(spaceinfo.SpaceCode);
|
|
|
int spinFlag = 0;
|
|
|
if (spaceCode % 2 == 0) //偶数 转180°
|
|
|
{
|
|
|
spinFlag = 4;
|
|
|
}
|
|
|
|
|
|
if (spaceinfo.SpaceArea == "A")
|
|
|
{
|
|
|
if (!_plc.WriteInt16("D2", spinFlag.ToString()))
|
|
|
{
|
|
|
throw new ArgumentException($"旋转角度下发至PLC失败");
|
|
|
}
|
|
|
if (!_plc.WriteInt16("D29", spaceCode.ToString()))
|
|
|
{
|
|
|
throw new ArgumentException($"货道号下发至PLC失败");
|
|
|
}
|
|
|
result = true;
|
|
|
}
|
|
|
else if (spaceinfo.SpaceArea == "B")
|
|
|
{
|
|
|
|
|
|
result = false;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 提取货道号
|
|
|
/// </summary>
|
|
|
/// <param name="input"></param>
|
|
|
/// <returns></returns>
|
|
|
private static string ExtractNumber(string input)
|
|
|
{
|
|
|
string pattern = @"\d+";
|
|
|
|
|
|
Match match = Regex.Match(input, pattern);
|
|
|
|
|
|
if (match.Success)
|
|
|
{
|
|
|
return match.Value.TrimStart('0');
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return null; // 或者返回默认值,如"0"
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 读取失败处理
|
|
|
/// </summary>
|
|
|
/// <param name="client"></param>
|
|
|
private void NoReadHandle(string client)
|
|
|
{
|
|
|
_logger.Error($"客户端:{client};读取失败!!!!!!");
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取成品库指定区域的货道信息
|
|
|
/// </summary>
|
|
|
/// <param name="spaceArea"></param>
|
|
|
/// <returns></returns>
|
|
|
public List<BaseSpaceInfo> GetBaseSpaceinfos(string spaceArea)
|
|
|
{
|
|
|
_spaceinfoService.GetSpaceInfosByExpression(out List<BaseSpaceInfo> spaceinfos, x => x.StoreCode == _appConfig.storeCode && x.SpaceArea == spaceArea);
|
|
|
|
|
|
return spaceinfos;
|
|
|
}
|
|
|
}
|
|
|
}
|